首先要明白工作的过程:组件通过dispatch action去触发store里面的reducer,然后reducer返回一个新的state去改变store里面的值。我们dispatch的action里面必须写明白type是啥,这样reducer里面进行switch action.type的时候才能匹配到需要return的state是什么样的,因为可能没有匹配的type,所以reducer必须写一个默认的return state。
然后开始通过例子说明:
从actions开始吧。 actions其实就是一个对象,这个对象留着给组件dispatch给reducer。我们经常看到的是返回action对象的函数。像这样子
function addOne() {//+1
return {
type: 'ADD_ONE'
}
}
function reduceOne() {//-1
return {
type: "REDUCE_ONE"
}
}
function addCustomNumber(number) {//接收一个参数,等着给reducer取出来去改变state的值
return {
type: "ADD_CUSTOM_NUM",
number
}
}
接下来是reducer,也就是和我们的state产生联系的纯函数。它接收两个参数,第一个是state,可以赋值一个state的初始状态,第二个参数是action,也就是我们的组件通过dispatch一个action的时候,store会把这个action作为参数传给reducer。
const initialState = {count: 0};
const counter = (state = initialState, action) => {
switch (action.type) {
case 'ADD_ONE':
return { count: state.count + 1};
case 'REDUCE_ONE':
return { count: state.count - 1};
case 'ADD_CUSTOM_NUM':
debugger
return { count: state.count + action.number}
default:
return state;
}
}
store: 一个应用只有一个store,createStore接收reducer作为参数。如果有多个reducer可以用combineReducer把多个reducer结合在一起传给createStore。
const store = createStore(counter);//创建store,把reducer和state联系起来
组件:通过connect(mapStateToProps, mapDispatchToProps)(组件) 可以访问到store里面特定的state和action,避免因为监听所有state变化造成性能问题。在mapDispatchToProps里面可以用bindActionCreators把dispatch和action creator绑定在一起,这样就直接调用action creator函数就相当于直接dispatch了。最后,要把连接后的组件写在provider里面,才能正常访问到store。于是乎,又回到那个观点,组件触发dispatch action, store里面的reducer会判断action的类型,然后返回新的state,state的变化也会触发组件的更新。
export class Counter extends React.Component {
render() {
const { count, addOne, reduceOne, addCustomNumber } = this.props;
return <div>
<button onClick={addOne}>+</button>
<span>{count}</span>
<button onClick={reduceOne}>-</button>
<button onClick={() => addCustomNumber(5)}>add five</button>
</div>
}
}
function mapStateToProps(state) {
return {count: state.count}
}
function mapDispatchToProps(dispatch) {
//这样写就不用在组件里面还要去dispatch啦,直接把dispatch和actions createor绑定在一起,
// 调用actions creator函数就是调用dispatch actions
return bindActionCreators({addOne, reduceOne, addCustomNumber}, dispatch);
}
const WrappedCounter = connect(mapStateToProps, mapDispatchToProps)(Counter);//组件和store, actions连接起来,从而能在组件里面访问store和actions