Redux浅析
Redux设计思想
- 唯一数据源
- 保持状态只读
- 数据改变只能通过纯函数完成
Redux工作模式
import {createStore} from 'redux';
import reducer from './Reducer.js';
const initValues = {
'First': 0,
'Second': 10,
'Third': 20
};
const store = createStore(reducer, initValues);
export default store;
component 组件本身上就做两件事情: 处理状态和处理模板;
所以,可以把组件拆分为两种组件: 处理状态的组件称为容器组件; 处理模板的组件称为傻瓜组件;
其中
import {Provider} from 'react-redux'; // Provider就是容器组件,用来从组件的顶层注入store
因此,所有的子组件就可以获得到store数据了,这样一来,傻瓜组件就比较简单了,不再需要维持组件的状态了.
import {connect} from 'react-redux';
function Counter({caption, onIncrement, onDecrement, value}) {
return (
<div>
<button onClick={onIncrement}>+</button>
<button onClick={onDecrement}>-</button>
<span>{caption} count: {value}</span>
</div>
);
}
// 把store中状态数据提供给组件使用(ownProps表示父组件的属性)
function mapStateToProps(state, ownProps) {
return {
// 提供给view使用的状态
// 名字必须与组件结构参数value一致
value: state[ownProps.caption]
}
}
// 组件内部的行为与props中行为进行绑定(本质上就是把组件内部的行为转化为分发action的动作)
function mapDispatchToProps(dispatch, ownProps) {
return {
// 组件绑定的事件---映射到分发逻辑
// 名字必须与组件结构参数onIncrement onDecrement一致
onIncrement: () => {
dispatch(Actions.increment(ownProps.caption));
},
onDecrement: () => {
dispatch(Actions.decrement(ownProps.caption));
}
}
}
// connect的作用就是产生一个容器组件,从而包装一个傻瓜组件(只有模板,没有状态的组件)
export default connect(mapStateToProps, mapDispatchToProps)(Counter);
因为组件内部的行为已经在组件内部转化为分发action的动作,所以需要声明component触发各种行为(与组件内名字保持一致)
export const increment = (counterCaption) => {
return {
type: ActionTypes.INCREMENT,
counterCaption: counterCaption
};
};
export const decrement = (counterCaption) => {
return {
type: ActionTypes.DECREMENT,
counterCaption: counterCaption
};
};
当页面上触发了对应的Action,就会dispatch派发到reducer,执行switch case对应条件的代码;
然后会返回一个新的state,而store提供数据存储,所以使用import reducer from './Reducer.js’将reducer生成 的new state拿到又存储起来
export default (state, action) => {
const {counterCaption} = action;
switch (action.type) {
case ActionTypes.INCREMENT:
return {...state, [counterCaption]: state[counterCaption] + 1};
case ActionTypes.DECREMENT:
return {...state, [counterCaption]: state[counterCaption] - 1};
default:
return state
}
}
如此循环,这样就形成了单向数据流;我们可以监控所有的状态数据的变化,不会遗漏.