Redux 简要的说就是一个事件分发器和全局
state
控制台。react
Redux 有一个全局的state
,经过将根组件包进Provider
,将store
分发给全部的子组件,而子组件经过connect
方法,获取dispatch
事件分发函数,以及须要的props
(若是有须要也能够经过connect
传入想分发给子组件的action
)npm
// Reducer/ConstValue.js export const ADD_NEW = 'add_new'; export const INCREASE = 'increase'; export const DECREASE = 'decrease'; export const DELETE = 'delete'; export INITIAL_STATE = { objList: [ { number: 0 } ] }; // Reducer/ActionCreator.js import { ADD_NEW, DELETE INCREASE, DECREASE } from './ConstValue'; export function addNew(obj) { return { type: ADD_NEW, obj } } export function delete(index) { return { type: DELETE, index } } export function increase(number, index) { return { type: INCREASE, number, index } } export function decrease(number, index) { return { type: DECREASE, number, index } }
Reducer 会注册给 store,用于处理 action 事件redux
// Reducer/Reducers.js import { ADD_NEW, DELETE INCREASE, DECREASE, INITIAL_STATE } from './ConstValue'; let objList = INITIAL_STATE.objList; export function objList(state=objList, action) { switch (action.type) { case ADD_NEW: return [...state, action.obj]; case DELETE: return [...state.slice(0, action.index), ...state.slice(action.index + 1) ]; case INCREASE: case DECREASE: return [...state.slice(0, action.index), Object.assign({}, state[action.index], {number: number(state[action.index].number, action)}), ...state.slice(action.index + 1) ]; default: return state; } } export function number(state=objList[0].number, action) { switch (action.type) { case INCREASE: return state + action.number; case DECREASE: return state - action.number; default: return state; } }
IMPORTANT数组
Reducer 传入(state, action), 经过判断action
的type
, 进行事件分发处理。当事件不少的时候能够把 Reducer 拆分, 最后经过combineReducers
进行组合。架构
每一个 Reducer 都要有明确的返回值,当siwtch
到default
的时候则返回传入的state
自己。在处理state
的时候,不要在原有参数上修改, 而应该返回一个新的参数, 例如app
return Object.assign({}, state[0], {number: action.number}); // 经过Object.assign获取一份state[0]的拷贝, 并修改state[0]中的number数据 return [...state, action.obj]; // 经过[...XXX]获得一个新的数组, 并在最后加入action.obj
// Reducer/index.js import { combineReducers } from 'redux'; import * as appReducers from './Reducers'; export const AppReducer = combineReducers(appReducers);
上述代码中, 经过import * as appReducers
导出所有的 Reducer, 以后利用combineReducers
黑魔法快速的组合 Reducer ide
黑魔法发动条件函数
每一个 Reducer 的名称, 必须与它获取的 state 参数名称同样, 例如:spa
export function objList(state=objList, action){} export function number(state=objList[0].number, action){}
若是你任性的不想那么写, 那么就要:code
// Reducer/Reducers.js export function reducerA(state=objList, action){} export function reducerB(state=objList[0].number, action){} // Reducer/index.js import { combineReducers } from 'redux'; import { reducerA reducerB, } from './Reducers'; export function AppReducer(state, action) { return { objList: reducerA(state.objList, action), number: reducerB(state.objList[0].number, action) } }
// 安装React绑定库 sudo npm install --save react-redux
在根组件上, 经过Provider
注入store
只有一个Store
// App/index.js import { Provider } from 'react-redux'; import { createStore } from 'redux'; import { AppReducer } from '../Reducer/index'; import RootComponent from './RootComponent'; let appStore = createStore(AppReducer); render( <Provider store={appStore}> <RootComponent /> </Provider>, document.getElementById('index_body') ); // App/RootComponent.js import ContentComponent from './ContentComponent'; class RootComponent extends Component { render() { return ( <div> <ContentComponent /> <div> ) } } export default ContentComponent;
注入store
后, 根组件全部的组件均可以获取到dispatch
函数, 以便进行action
的分发处理
// App/ContentComponent.js import { increase, decrease } from '../Reducer/ActionCreator'; class ContentComponent extends Component { render() { const {obj, increaseNumber, decreaseNumber} return ( <div> <span onClick={() => { increaseNumber(1); }}>加一</span> <span>{obj.number}</span> <span onClick={() => { decreaseNumber(1); }}>减一</span> </div> ) } } // 定义props筛选函数, 以state做为传入参数, 选出须要注入该组件做为props的state. 不是必须, 不写则state做为props所有注入 const mapStateToProps = (state) => { return { obj: state.objList[0] // objList: state.objList // 原本想写list增删逻辑的可是太懒了暂时搁浅.. } } // 定义action筛选函数, 以dispatch做为传入参数, 选出须要注入该组件须要使用的action. 不是必须 const mapDispatchToProps = (dispatch) => { return { increaseNumber: (number) => { dispatch(increase(number)); }, decreaseNumber: (number) => { dispatch(decrease(number)); } } } import { connect } from 'react-redux'; export default connect(mapStateToProps, mapDispatchToProps)(ContentComponent); // 不使用筛选函数的时候: // export default connect(mapStateToProps)(ContentComponent); // export default connect()(ContentComponent);
在经过connect
进行注入的时候, dispatch
已经做为组件的 props 而存在了。因此当须要传入的事件不少, 感受写mapDispatchToProps
很繁琐的时候, 还有另一种写法:
// App/ContentComponent.js import { increase, decrease } from '../Reducer/ActionCreator'; class ContentComponent extends Component { render() { const {obj, dispatch} return ( <div> <span onClick={() => { dispatch(increaseNumber(1)); }}>加一</span> <span>{obj.number}</span> <span onClick={() => { dispatch(decreaseNumber(1)); }}>减一</span> </div> ) } } import { connect } from 'react-redux'; export default connect(mapStateToProps)(ContentComponent);
经过 Redux, 咱们能够少些不少繁琐的事件传输。在 Redux 以前, 顶层组件处理 state 的改变, 而触发的事件则有可能须要层层传递给底层的子组件, 子组件触发以后再次层层回调传到顶层。
但 Redux 的 state 是全局的, 没必要关心哪一个组件触发setState()
函数, 只须要设定好action
和处理 action 的reducer
, 由store
进行分发处理。
那样的话, 咱们能够在底层触发 state 的改变而没必要担忧向上调用 --- 触发的 action 改变将被 store 监听, dispatch 给 reducer, reducer经过判断action.type
, 作出适当的反应处理 state
action 不少很繁琐
一开始的架构很重要,不然后期改动不易
淡化了传统React的组件传输事件与props的思想, 可能一开始不易理解