- 使用redux之前,基本的东西还是要懂的,数据流向介绍:
Action: 行为。它的作用就是将我们更新组件的状态(state)的每个动作抽象为一个行为,它有一个必须的参数type,定义了Action的名称,其他参数可自定义。写法:
{
type: 'TEST_ACTION',
key1: 'value',
...
keyN: value
}
因为Action是个对象,所以,我们需要创建这个对象,那创建这个对象的方法叫做ActionCreator,写法:
function testAction(key1: ?string, ..., keyN: ?string) {
return {
type: "TEST_ACTION",
key1: key1,
...
keyN: keyN
}
}
- Reducer: reducer的作用就是根据传入的Action行为和旧的state对象,返回一个新的state,然后组件会根据state刷新。当我们确定了组件的state对象结构和action行为的时候就可以编写reducer中的内容。写法:
function testReducer(state, action) { let key1 = action.key1; switch(action.type) { case TEST_ACTION: return { ...state, key1: key1 + '变化' }; default: return state; } }; export default testReducer;
当然我们的工程中可能会有多个reducer的情况,通过combineReducers可以将多个reducer合成统一管理。
import { combineReducers } from 'redux'; import testReducer1 from './testReducer1'; import testReducer2 from './testReducer2'; export default = combineReducers({ testReducer1, testReducer2 });
reducer是一个纯函数(同样的输入必须有同样的输出,需要遵循3个约束):
-
不可修改传入的参数。
-
一定要干净,没有API请求,没有变量修改,单纯执行计算,没有特殊情况。
-
调用非纯函数(Date.now()、Math.random()等),每次都会得到不同结果导致数据错误等安全问题。
-
当传入的state与旧state相比没有区别,返回的新state也应该一模一样。
-
Store: 当reducer返回了新的state后,这个state怎么传到组件和存储就成了问题,redux就是把这个状态统一放到store中进行管理。
import { createStore } from 'redux'; const store = createStore(reducers);
上面的代码根据reducers创建了一个store方法集(它并不是一个对象),然后再store中提供一些方法供我们使用。
// 获取当前 state store.getState() // 发送action,根据我们前面 注册的reducers 处理state store.dispath(action) // 替换当前 state 中的 reducer store.replaceReducer(nextReducer) // 添加监听 store.subscribe(listener)
此外redux有5个全局方法:
-
createStore:创建一个redux store来存储应用中所有的state,应用中只能存在一个store
createStore(reducer, [initialState],enhancer);
-
combineReducers: 把多个reducer函数作为value的object,合并成一个reducers函数,然后就可以通过reducers调用各个子reducer,state对象的结构由传入的多个reducer的key决定。
combineReducers(...reducers)
...middlewares:每个middleware接受store的dispatch和geiState函数作为命令参数,并返回一个函数。
-
该函数会被传入被称为next的下一个middleware的dispatch方法,并返回一个接受action的新函数,这个函数可以直接调用next(action),或者在其他需要的时刻调用,也可不调用。
-
调用链的最后一个middleware会接受真实的store的dispatch方法作为next参数,并结束调用链。所以middleware的函数为({getState,dispatch})=> next => action。
-
返回值:一个应用了middleware后的store enhancer。这个store enhancer就是一个函数,并且需要应用到creareStore。它会返回一个应用了middleware的新createStore。
-
bindActionCreators
:把 actionCreators 转曾拥有同名 keys 的对象,让 dispatch 把每个 actionCreator 包装起来,这样就可以直接调用它们。唯一使用 bindActionCreators 的场景是需要把 actionCreator 往下传到一个组件上,却不想让这个组件察觉到 redux 的存在,而且不希望把 redux store 或者 dispatch 传给它。bindActionCreators:把 actionCreators 转曾拥有同名 keys 的对象,让 dispatch 把每个 actionCreator 包装起来,这样就可以直接调用它们。唯一使用 bindActionCreators 的场景是需要把 actionCreator 往下传到一个组件上,却不想让这个组件察觉到 redux 的存在,而且不希望把 redux store 或者 dispatch 传给它。
返回值:一个与原对象类似的对象,只不过这个对象中的每个函数值都直接dispatch action。如果传入的是个函数返回的也是函数。
-
compose(...fuctions)
:当需要多个 store 增强器 依次执行的时候使用它。compose 在应用常见的两个用法:// 1 let buildStore = compose( applymiddleware(thunk) )(createStore) // 2 let initStore = compose( applymiddleware(thunk) )
参数1(arguments):合成多个函数。每个函数接收一个函数作为参数,然后返回一个函数。参数2(Function):从右往左吧接收到的函数合成后的终极函数。
Reat-redux需要知道的那些事
终于进入正题了,为了在react-native中使用redux,开发者提供了react-redux,基础工作原理不变,只不过多了写方法和参数,所以这边就需要继续了解一下,一下内容整理自官方文档:
- <Provider store>:使组件层级中的connect()方法能够得到redux-store。正常情况下,我们的根组件应该嵌套在其中。
- 属性(store):项目中唯一的redux store。
- 属性(children):组件层级的跟组件。
- connect([mapStateToProps],[mapDispatchToProps],[mergeProps],[options]);链接react组件和redux store。
- 参数(mapStateToProps(state, [ownProps]): stateProps):定义了这个参数,组件会监听 redux store 的变化,在任何情况下,只要 redux store 发送变化, mapStateToProps 函数就会被调用。也就是说:mapStateToProps负责返回需要传递给子组件的 state 这个函数必须返回一个纯对象,这个对象会与组件的props合并,如果省略这个参数,组件将监听不到redux store.
如果指定改回调函数中的第二个参数 ownProps,这个参数的值为传递到组件的props,而且只要组件接到新的 props,mapStateToProps 也会被调用。
-
参数(mapDispatchToProps(dispatch, [ownProps]): dispatchProps):负责返回一个 dispatchProps,dispatchProps 是actionCreator的key和dispatch(action)的组合。
-
如果传递一个对象,那么每个定义在该对象的函数都将被当做 redux action creator,而且这个对象会与 redux store 绑定在一起,其中所定义的方法名将作为属性名,合并到组件的 props 中。
-
如果传递的是一个函数,该函数将接收一个 dispatch 函数,然后由我们自己决定如何返回一个对象,这个对象通过 dispatch 函数与 action creator 以某种方式绑定在一起(提示:你也许会用到 Redux 的辅助函数bindActionCreators())。
-
如果你省略这个 mapDispatchToProps 参数,默认情况下,dispatch 会注入到你的组件 props 中。
-
如果指定了该回调函数中第二个参数 ownProps,该参数的值为传递到组件的 props,而且只要组件接收到新props,mapDispatchToProps 也会被调用。
-
-
参数(mergeProps(stateProps, dispatchProps, ownProps): props (Function)):如果指定了这个参数,mapStateToProps() 与 mapDispatchToProps() 的执行结果和组件自身的 props 将传入到这个回调函数中。该回调函数返回的对象将作为 props 传递到被包装的组件中。你也许可以用这个回调函数,根据组件的 props 来筛选部分的 state 数据,或者把 props 中的某个特定变量与 action creator 绑定在一起。如果你省略这个参数,默认情况下返回 Object.assign({}, ownProps, stateProps,dispatchProps) 的结果。
-
参数(options (Object)) 如果指定这个参数,可以定制 connector 的行为。
- [pure = true] (Boolean): 如果为 true,connector 将执行 shouldComponentUpdate 并且浅对比mergeProps 的结果,避免不必要的更新,前提是当前组件是一个“纯”组件,它不依赖于任何的输入或 state 而只依赖于 props 和 Redux store 的 state。默认值为 true。
- [withRef = false] (Boolean): 如果为 true,connector 会保存一个对被包装组件实例的引用,该引用通过 getWrappedInstance() 方法获得。默认值为 false。
-
返回值:根据配置信息,返回一个注入了 state 和 action creator 的 React 组件。
-
静态属性:WrappedComponent (Component): 传递到 connect() 函数的原始组件类。
-
静态方法:组件原来的静态方法都被提升到被包装的 React 组件。
-
实例方法:getWrappedInstance(): ReactComponent;仅当 connect() 函数的第四个参数 options 设置了 { withRef: true } 才返回被包装的组件实例。
-