摘要:設(shè)計(jì)思想應(yīng)用是一個(gè)狀態(tài)機(jī)試圖與狀態(tài)是一一對(duì)應(yīng)的所有的狀態(tài)保存在一個(gè)對(duì)象里基本改變和就是保存數(shù)據(jù)的地方你可以把它看成一個(gè)容器整個(gè)應(yīng)用只能有一個(gè)提供這個(gè)函數(shù)用來(lái)生成函數(shù)接受另一個(gè)函數(shù)作為參數(shù)返回新生成的對(duì)象對(duì)象包含所有數(shù)據(jù)如果想得到某個(gè)時(shí)點(diǎn)的數(shù)
設(shè)計(jì)思想
1.web應(yīng)用是一個(gè)狀態(tài)機(jī),試圖與狀態(tài)是一一對(duì)應(yīng)的.
2.所有的狀態(tài),保存在一個(gè)對(duì)象里.
1.Store
Store就是保存數(shù)據(jù)的地方,你可以把它看成一個(gè)容器,整個(gè)應(yīng)用只能有一個(gè)Store.
Redux提供createStore這個(gè)函數(shù),用來(lái)生成Store.
import { createStore } from "redux"; const store = createStore(reducer); createStore函數(shù)接受另一個(gè)reducer函數(shù)作為參數(shù),返回新生成的Store對(duì)象.
2.State
State對(duì)象包含所有數(shù)據(jù),如果想得到某個(gè)時(shí)點(diǎn)的數(shù)據(jù),就要對(duì)Store生成快照,這種時(shí)點(diǎn)的數(shù)據(jù)集合,
就叫做State.當(dāng)前時(shí)刻的State,可以通過(guò)store.getState()拿到.
const state = store.getState();
3.Action
state的變化,會(huì)導(dǎo)致view的變化,但是,用戶接觸不到state,只能接觸到view,所以.stated的變化必須是view導(dǎo)致的.Action就是view發(fā)出的通知,表示state應(yīng)該要發(fā)生變化了.
Action是一個(gè)對(duì)象,其中的type屬性是必須的,表示Action的名稱,其他屬性可以自由設(shè)置.
const action = { type: "ADD_TODO", payload: "learn Redux" };
Action的名稱是ADD_TODO,它攜帶的信息是字符串Learn Redux.
可以這樣理解,Action描述當(dāng)前發(fā)生的事情,改變State的唯一方法,就是使用Action,它會(huì)運(yùn)送數(shù)據(jù)到Store.
4.Action Creator
View要發(fā)送多少種信息,就會(huì)有多少種Action,可以定義一個(gè)函數(shù)生成Action,這個(gè)函數(shù)就叫ActionCreator.
const ADD_TODO = "添加 TODO"; function addToDo(text) { return { type: ADD_TODO, text } }
5.store.dispatch()
store.dispatch()是view發(fā)出Action的唯一方法.
store.dispatch(addTODO("Learn Redux"));
6.reducer
store收到Action以后,必須給出一個(gè)新的State,這樣view才會(huì)發(fā)生變化.
這種State的計(jì)算過(guò)程就叫做Reducer.
Reducer是一個(gè)函數(shù),他接受Action和當(dāng)前State作為參數(shù),返回一個(gè)新的State.
export default (state = 0, action) => { switch (action.type) { case "INCREMENT": return state + 1; case "DECREMENT": return state - 1; case "getSource": return "bbbb"; default: return 0; } }
reducer函數(shù)收到名為ADD的action以后,就返回一個(gè)新的state,作為加法的計(jì)算結(jié)果,其他計(jì)算的邏輯,
也可以根據(jù)Action的不同來(lái)實(shí)現(xiàn).
實(shí)際應(yīng)用中,Reducer函數(shù)不用像上面這樣手動(dòng)調(diào)用,store.dispatch方法會(huì)觸發(fā)Reducer的自動(dòng)執(zhí)行.
為此,Store需要知道Reducer函數(shù),做法就是生成Store的時(shí)候,將Reducer傳入createStore方法.
const store = createStore(reducer);
createStore接受Reducer作為參數(shù),生成一個(gè)新的Store.以后每當(dāng)store.dispatch發(fā)送過(guò)來(lái)一個(gè)新的Action,
就會(huì)自動(dòng)調(diào)用Reducer,得到新的State.
7.純函數(shù)
Reducer函數(shù)最重要的特征是,它是一個(gè)純函數(shù),也就是說(shuō),只要是同樣的輸入,必須得到同樣的輸出.
由于Reducer是純函數(shù),就可以保證同樣的State,必定得到同樣的view,但正因?yàn)檫@一點(diǎn),Reducer函數(shù)里面不能改變
State,必須返回一個(gè)全新的對(duì)象.
return Object.assign({}, state, { thingToChange }) export default (state = 0, action) => { switch (action.type) { case "INCREMENT": return state + 1; case "DECREMENT": return state - 1; case "getSource": return "bbbb"; case "ajax": return action.data; case "ajaxError": return action.data default: return 0; } }
8.store.subscribe()
Store允許使用store.subscribe方法設(shè)置監(jiān)聽(tīng)函數(shù),一旦State發(fā)生變化,就自定執(zhí)行這個(gè)函數(shù).
store.subscribe(listener);
顯然,只要把view的更新函數(shù)(render或this.setState)放入listen,就會(huì)實(shí)現(xiàn)view的自動(dòng)渲染.
let unsubscribe= store.subscribe(() => console.log(store.getState()));
unsubscribe();
1.store.getState(),store.dispatch(),store.subscribe()
let { subscribe, dispatch, getState } = createStore(reducer);Reducer的拆分
Reducer函數(shù)負(fù)責(zé)生成State,由于整個(gè)應(yīng)用只有一個(gè)state對(duì)象,包含所有數(shù)據(jù),對(duì)于大型應(yīng)用來(lái)說(shuō),這個(gè)State
必然十分龐大,導(dǎo)致Reducer函數(shù)也十分龐大.
Redux提供了一個(gè)combineReducers方法,用于Reducer的拆分,你只要定義各個(gè)子Render函數(shù),
然后用這個(gè)方法,將它們合成一個(gè)大的Reducer.
import { combineReducers } from "redux"; const chatReducer = combineReducers({ chatLog, statusMessage, userName })工作流程
1.用戶發(fā)出Action
store.dispatch(action);
2.Store自動(dòng)調(diào)用Reducer,并且傳入兩個(gè)參數(shù),當(dāng)前State和收到的Action.Reducer會(huì)返回新的State.
let nextState = todoApp(previousState, action);
3.State一旦有變化,Store就會(huì)調(diào)用監(jiān)聽(tīng)函數(shù).
store.subscribe(listener);
4.listener可以通過(guò)store.getState()得到當(dāng)前狀態(tài),如果使用的是React,這時(shí)可以觸發(fā)重新渲染view.
function listerner() { let newState = store.getState(); component.setState(newState); }實(shí)例
import React, { Component } from "react"; import { render } from "react-dom"; import reducer from "../reducers/reducer.js"; import { createStore } from "redux"; const store = createStore(reducer); class App extends Component { constructor(props) { super(props); this.state = { count: 0, source: "aaaa", ajaxSource: "ajax" }; } handleAdd = () => { store.dispatch({ type: "INCREMENT" }); } handleDel = () => { store.dispatch({ type: "DECREMENT" }); } handleGet = () => { store.dispatch({ type: "getSource" }) } handleAjax = () => { fetch("../api/response.json") .then(response => response.json()) .then((res) => { store.dispatch({ type: "ajax", data: res }); }).catch((err) => { store.dispatch({ type: "ajaxError", data: err }); }) } render() { let _this = this; store.subscribe(() => { let o = store.getState(); _this.setState({ [o.type]: store.getState()[o.type] }) }); return ({ this.state.count } { this.state.source } { this.state.ajaxSource.res }); } } render(, document.getElementById("root"));
export default (state = 0, action) => { switch (action.type) { case "INCREMENT": return Object.assign({}, state, { count: state + 1, type: "count" }); case "DECREMENT": return Object.assign({}, state, { count: state - 1, type: "count" }); case "getSource": return Object.assign({}, state, { source: action.dada, type: "source" }); case "ajax": return Object.assign({}, state, { ajaxSource: action.data, type: "ajaxSource" }) case "ajaxError": return Object.assign({}, state, { ajaxSource: action.data, type: "ajaxSource" }); default: return state } }
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/84211.html
摘要:寫(xiě)在前頭簡(jiǎn)介隨著單頁(yè)應(yīng)用開(kāi)發(fā)日趨復(fù)雜,需要管理比任何時(shí)候都要多的狀態(tài)。如果一個(gè)的變化會(huì)引起另一個(gè)變化,那么當(dāng)變化時(shí),就可能引起對(duì)應(yīng)以及另一個(gè)的變化,依次地,可能會(huì)引起另一個(gè)的變化。一些庫(kù)如試圖在視圖層禁止異步和直接操作來(lái)解決這個(gè)問(wèn)題。 寫(xiě)在前頭 redux 簡(jiǎn)介 ? 隨著 JavaScript 單頁(yè)應(yīng)用開(kāi)發(fā)日趨復(fù)雜,JavaScript 需要管理比任何時(shí)候都要多的 state (...
摘要:主要用于構(gòu)建,被認(rèn)為是中的視圖。高效通過(guò)對(duì)的模擬,最大限度地減少與的交互。也就是說(shuō),用戶負(fù)責(zé)視覺(jué)層,狀態(tài)管理則是全部交給它。該回調(diào)函數(shù)必須返回一個(gè)純對(duì)象,這個(gè)對(duì)象會(huì)與組件的合并。 React 定義: React 是一個(gè)用于構(gòu)建用戶界面的 JAVASCRIPT 庫(kù)。React主要用于構(gòu)建UI,React 被認(rèn)為是 MVC 中的 V(視圖)。 特點(diǎn): 聲明式設(shè)計(jì) ?React采用聲明范式...
摘要:我們可以為元素添加屬性然后在回調(diào)函數(shù)中接受該元素在樹(shù)中的句柄,該值會(huì)作為回調(diào)函數(shù)的第一個(gè)參數(shù)返回。使用最常見(jiàn)的用法就是傳入一個(gè)對(duì)象。單向數(shù)據(jù)流,比較有序,有便于管理,它隨著視圖庫(kù)的開(kāi)發(fā)而被概念化。 面試中問(wèn)框架,經(jīng)常會(huì)問(wèn)到一些原理性的東西,明明一直在用,也知道怎么用, 但面試時(shí)卻答不上來(lái),也是挺尷尬的,就干脆把react相關(guān)的問(wèn)題查了下資料,再按自己的理解整理了下這些答案。 reac...
摘要:要求通過(guò)要求數(shù)據(jù)變更函數(shù)使用裝飾或放在函數(shù)中,目的就是讓狀態(tài)的變更根據(jù)可預(yù)測(cè)性單向數(shù)據(jù)流。同一份數(shù)據(jù)需要響應(yīng)到多個(gè)視圖,且被多個(gè)視圖進(jìn)行變更需要維護(hù)全局狀態(tài),并在他們變動(dòng)時(shí)響應(yīng)到視圖數(shù)據(jù)流變得復(fù)雜,組件本身已經(jīng)無(wú)法駕馭。今天是 520,這是本系列最后一篇文章,主要涵蓋 React 狀態(tài)管理的相關(guān)方案。 前幾篇文章在掘金首發(fā)基本石沉大海, 沒(méi)什么閱讀量. 可能是文章篇幅太長(zhǎng)了?掘金值太低了? ...
摘要:兄弟組件之間無(wú)法直接通信,它們需要利用同一層的上級(jí)作為中轉(zhuǎn)站。在兩個(gè)地方會(huì)用到,一是通過(guò)提交后需要拿到里面的數(shù)據(jù),二是利用監(jiān)聽(tīng)到發(fā)生變化后調(diào)用它來(lái)獲取新的數(shù)據(jù)。 前言 在學(xué)習(xí)react的過(guò)程中,深深的被react的函數(shù)式編程的模式所吸引,一切皆組件,所有的東西都是JavaScript。React框架其實(shí)功能很單一,主要負(fù)責(zé)渲染的功能,但是社區(qū)很活躍,衍生出了很多優(yōu)秀的庫(kù)和工具。個(gè)人覺(jué)得...
摘要:而函數(shù)式編程就不一樣了,這是模仿我們?nèi)祟惖乃季S方式發(fā)明出來(lái)的。數(shù)據(jù)流在中,數(shù)據(jù)的流動(dòng)是單向的,即從父節(jié)點(diǎn)傳遞到子節(jié)點(diǎn)。數(shù)據(jù)流嚴(yán)格的單向數(shù)據(jù)流是架構(gòu)的設(shè)計(jì)核心。 前言 總括: 本文采用react+redux+react-router+less+es6+webpack,以實(shí)現(xiàn)一個(gè)簡(jiǎn)易備忘錄(todolist)為例盡可能全面的講述使用react全家桶實(shí)現(xiàn)一個(gè)完整應(yīng)用的過(guò)程。 代碼地址:Re...
閱讀 2770·2021-11-23 09:51
閱讀 3529·2021-10-08 10:17
閱讀 1262·2021-10-08 10:05
閱讀 1310·2021-09-28 09:36
閱讀 1833·2021-09-13 10:30
閱讀 2174·2021-08-17 10:12
閱讀 1670·2019-08-30 15:54
閱讀 2004·2019-08-30 15:53