In React JS Tutorials, lectures from 9. html
From: React高级篇(一)从Flux到Redux,react-reduxreact
从Flux到Redux,再到react-redux,从这个简短历程中,咱们能够看到框架设计上的演进,而redux + react-redux也是React开发万家桶的标配。git
到了这里,能够忘记Flux啦~github
[React] 07 - Flux: react communicates with mongodb mongodb
[React] 11 - Redux: reduxredux
[React] 12 - Redux: async & middleware数组
[React] 13 - Redux: react-redux架构
[React] 14 - Redux: Redux Sagamvc
[React] 15 - Redux: TodoMVC 框架
文档:https://redux.js.org/basics/example-todo-list
结合Redux-saga 中文文档,乃高手必备之物。
江湖有云:先实践一下,而后再看以上文档和示例代码。
详述:[React] 07 - Flux: react communicates with mongodb
实现的思路要点:
1. 在store中有一个数组(state)来表现new item。
2. 点击按钮,发送信号(action),改变状态,view监听到状态后刷新(从新表现items)
dispatch与store的问题,过于灵活。
参考:[React] 02 - Intro: why react and its design pattern - 背后的思想:一步一步进化到 Redux
学习: 《看漫画,学 Redux》 —— A cartoon intro to Redux
问题1:store 的代码没法被热替换,除非清空当前的状态
改变下store的代码,状态没了!不利于调试(热替换)。
分开保存便可。
问题2:每次触发 action 时状态对象都被直接改写了
旧状态管理不稳定,很差实现 “跳回到这个对象以前的某个状态(想象一个撤销功能)”。
当一个 action 须要 store 响应时,将状态拷贝一份并在这份拷贝的状态上作出修改。
问题3:没有合适的位置引入第三方插件
一个简单的例子就是日志。好比说你但愿 console.log() 每个触发的 action 同时 console.log() 这个 action 被响应完成后的状态。
在 Flux 中,你只能订阅(subscribe) dispatcher 的更新和每个 store 的变更。
可是这样就侵入了业务代码,这样的日志功能不是一个第三方插件可以轻易实现的。
(1) 将这个架构的部分功能包装进其余的对象(中间件)中将使得咱们的需求变得更容易实现;
Goto: [React] 12 - Redux: async & middleware
(2) 使用一个树形结构来组织全部改变状态的逻辑。
学习: 《看漫画,学 Redux》 —— A cartoon intro to Redux
1. Action creators
保留了 Flux 中 action creator 的概念。
Redux 中的 action creator 不会直接把 action 发送给 dispatcher,而是返回一个格式化好的 JavaScript 对象。
2. The store
Redux 中的 store 首先会保存整个应用的全部状态,而后将判断 "哪一部分状态须要改变" 的任务分配下去。
而以 root reducer 为首的 reducer 们将会承担这个任务。
store 已经彻底接管了 dispatch 相关的工做。
3. The reducers
当 store 须要知道一个 action 触发后状态须要怎么改变时,他会去询问 reducer。
Root reducer 会根据状态对象的键(key)将整个状态树进行拆分,而后将拆分后的每一块子状态传到知道该怎么响应的子 reducer 那里进行处理。
【状态树,子状态,子 reducer】
4. 拷贝state后修改
这是 Redux 的核心思想之一。不直接修改整个应用的状态树,而是将状态树的每一部分进行拷贝并修改拷贝后的部分,而后将这些部分从新组合成一颗新的状态树。
子 reducers 会把他们建立的副本传回给根 reducer,而根 reducer 会把这些副本组合起来造成一颗新的状态树。最后根 reducer 将新的状态树传回给 store,store 再将新的状态树设为最终的状态。
若是你有一个小型应用,你可能 只有一个 reducer 对整个状态树进行拷贝并做出修改。
又或者你有一个超大的应用,你可能会有 若干个 reducers 对整个状态树进行修改。这也是 Flux 和 Redux 的另外一处区别。
在 Flux 中,store 并不须要与其余 store 产生关联,并且 store 的结构是扁平的。
而在 Redux 中,reducers 是有层级结构的。这种层级结构能够有若干层,就像组件的层级结构那样。
4.1 Immutable for Object
4.2 concat for Array
4.3 filter for Array
4.4 定制化 硬拷贝
详情请见: [React] 11 - Redux: redux
React JS Tutorials - Redux部分
import { createStore } from "redux";
(2) 接收到动做信号
const reducer = (initialState=0, action) => {
...
}
const store = createStore(reducer, 1)
(3) 触发事件
/* 每次 改变的时候会执行一次这个函数 */
store.subscribe(() => {
console.log("store changed", store.getState());
})
(1) 发生一次用户动做
// store.dispatch({type: "INC"})
state
添加了更多的动做,触发了更多的事件。
Jeff: 多reducer的状况的处理方式。
import { combineReducers, createStore } from "redux";
/////////////////////////////////////////////////////////////////////////////////////////////////////// /**
* 放在单独的文件里为好
*/
const userReducer = (state={}, action) => { switch(action.type) { case "SET_NAME": { return {...state, name: action.payload}; break; } case "SET_AGE": { return {...state, age: action.payload}; break; } } return state; } // I would live in a separate file const tweetsReducer = (state=[], action) => { switch(action.type) { case "ADD_TWEET": { return state.concat({ id: Date.now(), //fake an ID by using a timestamp text: action.payload, }); break; } } return state; } ------------------------------------------------------------------------------------------------------- const reducers = combineReducers({ user: userReducer, tweets: tweetsReducer })
//////////////////////////////////////////////////////////////////////////////////////////////////////// const store = createStore(reducers) // state的默认值能够做为第二个参数,或者放在reducer的第一个init state定义
////////////////////////////////////////////////////////////////////////////////////////////////////////
store.subscribe(() => { console.log("store changed", store.getState()); })
//////////////////////////////////////////////////////////////////////////////////////////////////////// store.dispatch({type: "SET_NAME", payload: "Will"}) store.dispatch({type: "SET_AGE", payload: 35}) store.dispatch({type: "SET_AGE", payload: 34}) store.dispatch({type: "ADD_TWEET", payload: "OMG LIKE LOL"}) store.dispatch({type: "ADD_TWEET", payload: "I am so like seriously like totally like right now"})
请注意:做为对比,上例中的store.dispatch通常会写在onClick中,由用户触发,以下。
const render = () => ReactDOM.render( <Counter value={store.getState()} onIncrement={() => store.dispatch({ type: 'INCREMENT' })} onDecrement={() => store.dispatch({ type: 'DECREMENT' })} />, rootEl )
详见请见:[React] 12 - Redux: async & middleware
详见请见:[React] 13 - Redux: react-redux