redux
- Web 应用是一个状态机,视图与状态是一一对应的。
- 所有的状态,保存在一个对象里面。
redux不依赖于react
state
就是app中数据组成的树,也是一个普通的js对象。树的结构根据应用的需要自行决定,官方推荐的方式是分为三种数据:
- 后端提供的应用数据
- 应用状态数据 (某条数据是否选中)
- ui组件的数据(弹窗是否打开)
action
action是一个描述“发生了什么”的普通对象
action是我们开发的应用程序和store间通信的信息,它就是普通的js对象,结构是自定义的,信息量应尽可能小。
例如:
{ type: 'ADD_NEWS', text: '这是一条新闻' }
action creator
action创建函数
function addNews(text) { return { type: 'ADD_NEWS', text } }
reducer
reducer是根据action来返回一个全新state的纯函数。
function newsReducer(state = initialState, action) { switch (action) { case: 'ADD_NEWS': return [...state, text] break; default: return state; } }
store
store只是把actions和reducers联系在一起的对象,并不是传统意义上象征数据的东西。
const store = createStore(rootReducer, defaultState)
提供 getState() 方法获取 state
提供 dispatch(action) 方法更新 state; store.dispatch(addNews(‘这是一条新闻’))
通过 subscribe(listener) 注册监听器
通过 subscribe(listener) 返回的函数注销监听器。
react-redux
容器组件(container)和展示组件(component)
component只关注展示层。
container是通过connect方法把redux和展示组件关联起来的东西。
combineReducers
combineReducers(reducers)
传入reducers作为参数, reducers是一个object,如 {news: function() {…}, blogs: function() {…}}
返回一个遍历执行所有reducers的reducer函数,每个reducer只处理state中对应自己key的部分.
bindActionCreators
bindActionCreator
function bindActionCreator(actionCreator, dispatch) { return (...args) => dispatch(actionCreator(...args)) }
bindActionCreators就是把多个actionCreator变成会去执行dispatch的函数,并且返回这个对象。
connect
连接 React 组件与 Redux store。连接操作不会改变原来的组件类。反而返回一个新的已与 Redux store 连接的组件类。
1.mapStateToProps
如果定义该参数,组件将会监听 Redux store 的变化。任何时候,只要 Redux store 发生改变,mapStateToProps 函数就会被调用。该回调函数必须返回一个纯对象,这个对象会与组件的 props 合并。如果你省略了这个参数,你的组件将不会监听 Redux store。如果指定了该回调函数中的第二个参数 ownProps,则该参数的值为传递到组件的 props,而且只要组件接收到新的 props,mapStateToProps 也会被调用(例如,当 props 接收到来自父组件一个小小的改动,那么你所使用的 ownProps 参数,mapStateToProps 都会被重新计算)
// 把state上的todos绑定到 组件.props.todos function mapStateToProps(state) { return { todos: state.todos } } export default connect(mapStateToProps)(TodoApp)
2.mapDispatchToProps
(Object or Function): 如果传递的是一个对象,那么每个定义在该对象的函数都将被当作 Redux action creator,而且这个对象会与 Redux store 绑定在一起,其中所定义的方法名将作为属性名,合并到组件的 props 中。如果传递的是一个函数,该函数将接收一个 dispatch 函数,然后由你来决定如何返回一个对象,这个对象通过 dispatch 函数与 action creator 以某种方式绑定在一起(提示:你也许会用到 Redux 的辅助函数 bindActionCreators())。如果你省略这个 mapDispatchToProps 参数,默认情况下,dispatch 会注入到你的组件 props 中。如果指定了该回调函数中第二个参数 ownProps,该参数的值为传递到组件的 props,而且只要组件接收到新 props,mapDispatchToProps 也会被调用。
export function mapDispatchToProps(dispatch) { return bindActionCreators(actionCreators, dispatch); } // 下面两种方式效果一致 var App = connect(mapStateToProps, actionCreators)(Main); var App = connect(mapStateToProps, mapDispatchToProps)(Main);
Provider
包裹Provider让所有container都能访问store
store.dispatch(action)
store.dispath(action)会执行reducer(currentState, action)并return action。原生的dipatch只支持普通js对象来作为参数,否则会报错。
redux middleware
它提供的是位于 action 被发起之后,到达 reducer 之前的扩展点。(?)
其实就是在dispatch前后做一些额外的事情的一个函数,这个函数就是middleware, 有多个middlewares也就是嵌套地执行这多个函数。
const logger = ({ dispatch, getState }) => next => action => { console.log('dispatching', action) let result = next(action) console.log('next state', getState()) return result } export default function applyMiddleware(...middlewares) { return (createStore) => (reducer, preloadedState, enhancer) => { const store = createStore(reducer, preloadedState, enhancer) let dispatch = store.dispatch let chain = [] const middlewareAPI = { getState: store.getState, dispatch: (action) => dispatch(action) } chain = middlewares.map(middleware => middleware(middlewareAPI)) dispatch = compose(...chain)(store.dispatch) return { ...store, dispatch } } } const middlewares = [logger] const store = createStore( reducer, applyMiddleware(...middlewares) )
redux thunk
通过redux middleware实现支持dispatch一个函数。
function createThunkMiddleware(extraArgument) { return ({ dispatch, getState }) => next => action => { if (typeof action === 'function') { return action(dispatch, getState, extraArgument); } return next(action); }; } const thunk = createThunkMiddleware(); thunk.withExtraArgument = createThunkMiddleware; export default thunk;
转:https://segmentfault.com/a/1190000008287154
- 本文固定链接: http://madong.net.cn/index.php/2018/05/622/
- 转载请注明: 管理员 于 小东 发表