You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
functionsubscribe(listener){if(typeoflistener!=='function'){thrownewError('Expected listener to be a function.')}if(isDispatching){thrownewError(/* some error msg*/)}letisSubscribed=trueensureCanMutateNextListeners()nextListeners.push(listener)returnfunctionunsubscribe(){if(!isSubscribed){return}if(isDispatching){thrownewError(/* some error msg*/)}isSubscribed=falseensureCanMutateNextListeners()constindex=nextListeners.indexOf(listener)nextListeners.splice(index,1)}}
漫谈Redux & React-Redux 设计精髓
Redux 设计精髓
Redux 是为 Javascript 应用而生的可预估的状态容器,而React-Redux是针对React应用而提供的可预测状态管理机制。
Redux 由三部分组成:action,store,reducer。action顾名思义是你发起的一个操作,然后丢给reducer,reducer接收一个之前的state和action参数,然后返回一个新的 state 给 store(state 只允许在 reducer 中进行改变)。Store是一个容器,state 存储在这个容器中,redux规定Store仅能有唯一一个,而mobx可以有多个Store。
Store
在redux中,Store 管理着应用程序的状态,我们无法直接修改Store,唯一的方法是通过reducer,而唯一可以触发reducer的是通过Store去dispatch一个action(包含状态变更的信息)。因此,要改变数据,我们需要dispatch一个action。所以,redux应用数据的改变为:
Redux使用“Store”将应用程序的整个状态存储在一个地方。因此,所有组件的状态都存储在Store中,并且它们从Store本身接收更新。单状态树使跟踪 随时间的变化以及调试或检查应用程序变得更容易。
reducer
一个reducer是一个纯函数:
(previousState, action) => newState
,用来执行根据指定 action 来更新 state 的逻辑。reducer决定应用数据的改变纯函数即只要参数相同,相同的输入永远会有相同的输出,纯函数不能修改previousState。reducer每次都要返回一个新状态,新状态由旧状态和action决定。类似的:
Store中的数据通过dispatch action,但action只是提供了actionType和payload,并没有决定Store应如何更新。
reducer 接收actionType和payload,然后switch actionType,在相关条件下进行数据整合,最后结合原Store 的state和action对象生成新的state给Store,进行Store的更新
action 类型常量
其实action就是传递的数据(对象的形式),Redux将所有事件抽象为action。当dispatch action后,Store 收到了 Action 必须给出一个新的 State,这样 View 才会发生变化。这种 State 的计算过程就叫做 Reducer。
在大型项目中,为了项目规范,一般把action type定义为常量,单独放一个文件。
因此,redux缺点也是显而易见的,为了一个功能,既要写reducer,还要写action,还要单独写一个文件定义action type
源码简单分析
createStore对外暴露了dispatch,subscribe,getState和replaceReducer方法。
store.subscribe
注册的listener,并返回了unsubscribe
方法,用于注销当前listener。当store tree更新后,依次执行数组中的listener:compose调用了reduce方法,将形如fn(arg1)(arg2)(arg3)...的柯里化函数按照顺序执行。
compose(f, g, h)
形如(...args) => f(g(h(...args)))
,将函数h(...args)
得到的结果作为参数传给函数g,以此类推。例如:applyMiddleware接收中间件为参数,并返回一个createStore为参数的函数。中间件会在每次dispatch的时候执行。
applyMiddleware把中间件放在一个chain数组中,通过compose方法,让每个中间件按照顺序依次传入dispatch参数执行,再组合出新的dispatch
React-Redux
React-Redux
提供了两个重要的对象,<Provider store>
和connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])
。redux提供一个全局的Store, react 从 store 拿去数据,store 发生变化,react 重新进行渲染。redux与react-redux关系图
Provider
Provider 是在原有的 APP 上面包一层,然后接收 store 作为 props,然后给 connect 用。connect 接收 store 提供的 state 和 action,返回给我们的 react 组件
Provider内的组件要使用state中的数据,需要使用connect方法进行连接:
connect
connect函数是将React组件连接到Redux Store,允许我们将 store 中的数据作为 props 绑定到组件上。用法如下:
配合babel,使用es7 decorator:
decorator是一个对类进行处理的函数,第一个参数就是所要修饰的类。
对于多个reducer,redux也提供了
combineReducers
方法,可以把多个 reducer 合并成一个 root reducer,最后再将该reducer丢给createStore()
。Redux 数据流动
第一步:调用
store.dispatch(action)
如果在React项目中使用react-redux,则通过connect方法,可以将dispatch方法映射到props上。可以通过:
第二步:Redux Store调用rootReducer
redux 收到 action 过后,调用根 reducer 并返回最新的状态数据。
第三步:接收新状态并publish给订阅者
reducer函数负责处理数据,返回新的state(数据),state变化,触发
store.subscribe()
,所有订阅store.subscribe(listener)
的监听器都将被调用;监听器里可以调用 store.getState() 获得当前 state。The text was updated successfully, but these errors were encountered: