使用Redux的背景原因:
最近使用RN开发的一个业务模块时,遇到了这样的场景:A页面为内容呈现页面,B页面是通过点击A页面的按钮跳转过去的,然后在B页面操作选择数据之后需要把数据回传到A页面。
然后就去寻找看看项目中有没有什么好办法能实现,经过寻找发现了有通过发送通知的方式进行传值的,因为我们主要还是原生的页面,目前所有的RN页面都是通过一个原生的controller的壳子套着。所以如果采用发送通知的方式的话,这个流程就变成了:RN B页面发送数据回传路由 -> B页面原生代码中拦截到路由发送通知 -> A页面原生代码接收到通知与RN A页面交互传入B页面的数据。
这样明显太麻烦了,并且通知这种方式使用的场景多为一对多,总觉得有些不爽。后来通过前端大佬才知道Redux这个牛逼的框架,之后就开启了学习Redux的路线。。。
Redux学习参考文章:
- Redux中文文档,里面有详细的基础思想原理介绍,还有多个示例代码,对新手了解使用特别有帮助,强烈推荐
- 一个ToDo APP代码示例,感觉这个示例里面的代码写的更规范,更先进一些。左下部分有更多的demo,都可以在线查看学习。
Redux学习使用过程
Redux主要的3个重要组成及个人理解
1. Action:
描述你要定义的操作类型和数据,action内必须使用一个type字段来表示将要执行的动作。代码:
export const ChangeNickname = "ChangeNickname";
export const ChangeAge = "ChangeAge";
export const ResetInfo = "ResetInfo";
export const onChangeNickname = (nickname) => {
return {
type: ChangeNickname,
payload: {
nickname
}
}
}
export const onChangeAge = (age) => {
return {
type: ChangeAge,
payload: {
age
}
}
}
export const onResetInfo = () => {
return {
type: ResetInfo,
payload: {}
}
}
这里定义了名称为onSelectedModule和onChangeAge的action,并实现了action创建函数,也就是生成action的方法。
要注意下onChangeNickname内部中,return部分中一般都是用type来标识action类型,payload来标识数据部分。
2. Reducer:
Reducers指定了应用状态的变化如何响应actions并发送到store的,记住actions只是描述了有事情发生了这一事实,并没有描述应用如何更新state。可以理解成Reducers是沟通action与store之间的桥梁,将action的变化同步到store中。代码:
const defaultState = {
nickname: '小明',
age: 18
}
export default (state = defaultState, action) => {
switch (action.type) {
case ChangeNickname:
const { nickname } = action.payload;
return {
...state,
nickname
}
case ChangeAge:
const { age } = action.payload;
return {
...state,
age
}
case ResetInfo:
return defaultState
default:
return state
}
}
这里的state就是在stroe中存储的数据,defaultUserInfo是在初始化stroe时传的默认值。需要实现所有的action操作对应的数据变化,这里一定是要返回一个新的state数据,不能在原有的state中进行修改。
注意:这里在
switch的最后一定要加上default: return state;,进过尝试发现这行代码会在store初始化的时候执行,action是一个系统写入的名称,不会对应到自己定义的ActionType中,所以会走到default中,这时候的state值就是上面定义的defaultUserInfo,就达到了设置初始值的效果
3. Store:
Redux应用只有一个单一的store。当需要拆分数据处理逻辑时,你应该使用reducer组合,而不是创建多个store。
我理解的store就是一个类似单例的东西,生命周期跟随者整个应用,他的职责就是把数据存储起来。
使用起来有两个步骤:第一步是把你写的Reducer绑定到store中,第二步是在APP入口外层用Provider包一层,并且把store传进去。
const store = createStore(reducer);
ReactDOM.render(
<Provider store={store}>
<User />
</Provider>,
document.getElementById('root')
);
4. 数据调用和修改:
主要是通过connect方法进行属性的注入和数据同步。
const mapStateToProps = (state) => {
return {
nickname: state.nickname,
age: state.age
};
};
const mapDispatchToProps = {
onChangeNickname,
onChangeAge,
onResetInfo
}
export default connect(mapStateToProps, mapDispatchToProps)(User);