gif地址javascript
Web 应用是一个状态机,视图与状态是一一对应的。java
全部的状态,保存在一个对象里面。react
redux不依赖于reactgit
就是app中数据组成的树,也是一个普通的js对象。树的结构根据应用的须要自行决定,官方推荐的方式是分为三种数据:github
后端提供的应用数据redux
应用状态数据 (某条数据是否选中)后端
ui组件的数据(弹窗是否打开)app
action是一个描述“发生了什么”的普通对象
action是咱们开发的应用程序和store间通讯的信息,它就是普通的js对象,结构是自定义的,信息量应尽量小。
例如:ide
{ type: 'ADD_NEWS', text: '这是一条新闻' }
action建立函数函数
function addNews(text) { return { type: 'ADD_NEWS', text } }
reducer是根据action来返回一个全新state的纯函数。
function newsReducer(state = initialState, action) { switch (action) { case: 'ADD_NEWS': return [...state, text] break; default: return state; } }
store只是把actions和reducers联系在一块儿的对象,并非传统意义上象征数据的东西。
const store = createStore(rootReducer, defaultState)
提供 getState() 方法获取 state
提供 dispatch(action) 方法更新 state; store.dispatch(addNews('这是一条新闻'))
经过 subscribe(listener) 注册监听器
经过 subscribe(listener) 返回的函数注销监听器。
component只关注展现层。
container是经过connect方法把redux和展现组件关联起来的东西。
combineReducers(reducers)
传入reducers做为参数, reducers是一个object,如 {news: function() {...}, blogs: function() {...}}
返回一个遍历执行全部reducers的reducer函数,每一个reducer只处理state中对应本身key的部分.
bindActionCreator
function bindActionCreator(actionCreator, dispatch) { return (...args) => dispatch(actionCreator(...args)) }
bindActionCreators就是把多个actionCreator变成会去执行dispatch的函数,而且返回这个对象。
链接 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让全部container都能访问store
store.dispath(action)会执行reducer(currentState, action)并return action。原生的dipatch只支持普通js对象来做为参数,不然会报错。
它提供的是位于 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 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;