React Redux 源码简单分析
简单的使用示例:
import { Provider, connect } from './react-redux/src'
import { createStore } from './redux/src'
import rootReducer from './reducers'
const store = createStore(rootReducer)
function Child(props) {
return <div>
<div>name: {props.name}</div>
<div>age: {props.age}</div>
<button onClick={() => props.dispatch({
type: 'CHANGE_NAME',
data: Math.random()
})}
>
change name
</button>
<button onClick={() => props.dispatch({
type: 'CHANGE_AGE',
data: Math.random()
})}
>
change age
</button>
</div>
}
const mapStateToProps = state => {
return {
name: state.name,
age: state.age
}
}
const mapDispatchToProps = dispatch => ({
onClick: () => dispatch()
})
const ConnectChild = connect(
mapStateToProps,
// mapDispatchToProps
)(Child)
function Demo() {
return <Provider store={store}>
<ConnectChild />
</Provider>
}
export default Demo;1. Redux 源码
源码:https://github.com/reduxjs/redux/tree/v4.1.0
index.js 导出了以下内容:
1.1 createStore
源码简化版:
createStore 创建了一个 store 对象,含有
dispatch,subscribe,getState等方法大致原理是,内部通过闭包维护一个
currentState属性,nextListeners属性。nextListeners对应 观察者模式 中的观察者列表。subscribe方法可以往nextListeners中添加观察者当调用
dispatch方法是,会执行currentState = currentReducer(currentState, action)改变当前的currentState属性。之后会通知到所有的观察者去执行。而
getState方法可以获取最新的currentState方法。
2. React-Redux 源码
源码地址: https://github.com/reduxjs/react-redux/tree/v6.0.0
在 React-Redux 7.1 版本之后,引入 hooks 写法,老实说,源码可阅读性有点下降(是的,我没看懂...),因此,我们还是看旧版本的代码吧,大致思想应该是一致的
2.1 Provider 源码
源码简化版:
Provider 内部有
storeState和store两个 state在 componentDidMount 时调用
store.subscribe(), 内部会重新setState({ storeState }). 即当我们在子组件调用 dispatch 方法时, 会更新 Provider 组件的 storeState 状态。Provider 再通过 Context 将自己的 state 传递到子组件中
2.2 connectAdvanced.js 源码
被
connect()(Component)包裹的组件, 会通过selectDerivedProps(storeState, store)从 storeState 中得到你需要的属性 derivedProps (通过计算你的 mapStateTopProps 和 mapDispatchToState 得出)
3. 原理总结
在 Redux 库中,createStore() 返回 store 对象,对象上有
{ getState, dispatch, getState }等属性 ,该对象传给 React-Redux 的 Provider 组件React-Redux 中的 Provider 组件中通过 store.subscribe 监听 store 的状态数据变化。每次数据变化后都会把状态数据用 Context API 传递到子组件
当调用 dispatch 方法时,在 Redux 中会通过
currentState = currentReducer(currentState, action)也就是"过一遍" reducer 方法,得到最新的状态数据此时子组件会得到最新的 state 信息,通过
selectDerivedProps(storeState, store)来得到最终的 props,进行渲染。另外,如果发现从 store 中接受到的 props 没有发生变化,则不会重新渲染。
3.1 流程
Redux 中的三个概念:
dispatch
reducer
state
至于 Action Creator, 实际上就是为了便捷的创建 action,有更好,没有也行。
4. TODO
整理 compose,applyMiddleware,combineReducers,以及中间件的一个原理
Last updated
Was this helpful?