示例代码如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37index.js 文件
const store = createStore(counter, applyMiddleware(thunk))
ReactDom.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)
=========
app.js 文件
import React from 'react'
import { connect } from './mini-redux/mini-react-redux.js'
import { setAdd, setRemove, getAdd, getRemove } from './mini-redux/test-miniredux.js'
class App extends React.Component {
render() {
return (
<div>
<h2>现在的数值是 {this.props.num}</h2>
<button onClick={() => this.props.setAdd(2)}>加</button>
<button onClick={() => this.props.setRemove(3)}>减</button>
<button onClick={() => this.props.getAdd(3)}>过1秒加3</button>
<button onClick={() => this.props.getRemove(2)}>过1秒减2</button>
</div>
)
}
}
App = connect(
state => ({ num: state }), { setAdd, setRemove, getAdd, getRemove }
)(App)
export default App
执行步骤
- 执行 index.js 文件中的代码。
- 通过
const store = createStore(counter, applyMiddleware(thunk))初始化 redux。其中 createStore 接受 reducer 与 中间件。中间件暂且不表。 - createStore 函数返回
{ getState, subscribe, dispatch }对象.getState函数 返回currentStatesubscribe函数 负责监听currentState。当调用dispatch来更改currentState的时候会执行subscribe中收集的函数。用于更新组件dispatch接受reducer。通过reducer(actionCreator)方式更改currentState
- 通过
<Provider store={store}><App /></Provider>,挂载具体数据- 将
createStore的返回值store挂载到<Provider>组件上 <Provider>组件内部将store数据声明为全局可引用的getChildContext
- 将
- 执行 app.js 文件中的代码
- 通过
App = connect(state => ({ num: state }), { setAdd, setRemove, getAdd, getRemove } )(App)来重写App组件。 connect接受两个参数。- 第一个参数为
mapStateToProps一个匿名函数, - 第二个参数则是我们事先声明好的
action creator。 - connect作用负责将
<Provider>上传递过来的store放到使用connect组件的props上面
- 第一个参数为
connect运作原理- 声明一个
tempProps临时对象 - 首先通过
this.context拿到store。 - 在通过
store.getState()拿到stateProps数据后,将其放置到 临时对象tempProps上面。 - 在自性制作一个
bindActionCreators(actionCreators, store.dispatch)函数。 - 将各个
actionCreator用store.dispatch函数包裹住。 - 最后
bindActionCreators返回一个对象,其key值为各个actionCreator的名字。value值为store.dispatch(actionCreator())。 - 然后将此对象通过对象扩展运算符的方式加入到
tempProps临时对象上 - 最后将此临时对象挂载到 新的
<App>组件上 - 另外通过
store.subscribe监控 临时对象tempProps的改变。以便在currentState发生变化的时候,实时更新tempProps对象上的stateProps,因为用户使用了stateProps数据,它的变化继而可以引发视图的更新
- 声明一个
- 用户点击执行过程………
- 用户点击
加。 执行this.props.setAdd(2)语句 - 第8部讲过
actionCreator已经被dispatch包裹住了。- 实际上执行的语句为
store.dispatch(actionCreator())。 dispatch函数内部通过reducer(actionCreator)方式来更新currentState值。currentState发生改变后上面的tempProps临时对象跟随改变。通过props方式挂载到<App>上面的值发生更改。<App>组件中的this.props.num更改,视图自动更新!
- 实际上执行的语句为
中间件
- 如果传入了中间件。那么
createStore将作为参数传入applyMiddleware。 getState无变化。重点是dispatch。applyMiddleware内部 调用middleware中间件来重写dispatch方法- 即将用户传入的异步函数在中间件处。并且将
dispatch, getState作为参数传给异步函数。使异步函数可在内部调用dispatch(actionCreator)。 - 其余与上述基本一致
源码
react-boss
下载至本地后查看 redux 分支。里面有具体的注释说明