- 阅读react-redux源码 - 零
- 阅读react-redux源码 - 一
- 阅读react-redux源码(二) - createConnect、match函数的实现
react的技术栈一定会遇到redux,而在react中使用redux需要使用react-redux,那么react-redux是怎么包装redux已适用react的呢?
react-redux的原理是什么呢?
带着这些问题,翻看了react-redux的源码,小有收获,写博客以记,方便以后翻阅。
0. 准备
在继续之前先回顾一些redux、react和react-redux必要的知识。
redux
redux用于管理状态,可以响应状态的变化,简单描述下:
redux的createStore函数需要一个返回state的函数作为入参,这个函数被称作reducer。
调用createStore就能够得到一个store。这个store中就存储着state(reducer的返回值),并且可以通过store的subscribe方法来监听state的变化,当然也可以通过store提供的dispatch方法类修改state。
具体API如下:
// store.js
import { createStore } from 'redux'// 3. 下面store每dispatch一次reducer就会重新执行并计算一次state
function reducer(state = {a: 1}, action) {const { type, payload } = actionreturn payload
}// 0. 创建一个store
const store = createStore(reducer)// 1. 监听store中state的变更
store.subscribe((state) => {console.log(state)
})// 2. 发送一个action来通知reducer修改state
// {type: 'type1', payload: 1} 就是一个ation
store.dispatch({type: 'type1',payload: {a: 2}
})
react
react组件的更新原因可能是组件自身的state更新,组件的props更新,组件依赖的context更新导致的。但是放眼整个react应用的话,组件更新原因只有一个,就是祖先组件或者当前组件的state更新导致的。
react-redux
// App.js
import React, { Component } from 'react'
import { connect } from 'react-redux'class Example extends Component {render() {return <div onClick={this.props.dispatchA}>{this.props.a}</div>}
}function mapStateToProps(state) {return {...state}
}function mapDispatchToProps(dispatch) {return {dispatchA() => {dispatch({type: 'type', payload: {a: 10}})}}
}export default connect(mapStateToProps, mapDispatchToProps)(Example)
上面connect函数的调用返回了一个高阶组件,用高阶组件包裹Example组件之后就完成组件到redux的连接。
入口文件
// index.js
import { Provider } from 'react-redux'
import store from './store'
import App from './App.js'ReactDOM.render(<Privider store={store}><App /></Provider>)
可以看出来组件Example的props来自于父组件和store,再细分有父组件传给他的props和store的dispatch还有store的state。
小结
到这里我们有了一个redux的store,这个store会通过某些方法通知外部内部state的变化。
我们知道state的变化props的变化都会引起一个react组件的更新。
那么我们可以在store中state变化的时候通过设置组件state某个属性来通知组件有数据更新,然后组件更新的时候从store中拿到最新的数据用于render,理论上就可以实现在react应用中使用redux了。
1. 了解源码目录结构
该目录结构是react-redux@7.2.0版本的,其中我们主要关注connect文件夹和components文件夹下内容。connect目录下主要实现了connect方法,而component目录下则是用到的相关React组件,例如Provider和connect方法返回的高阶组件。
hooks目录则是redux的hooks用法的实现,utils则是用到的一些工具方法。
后面将重点阅读connect目录和componet目录下代码。
- 阅读react-redux源码 - 零
- 阅读react-redux源码 - 一
- 阅读react-redux源码(二) - createConnect、match函数的实现