乐趣区

深入理解redux

深入 Redux
简述
在快速理解 redux 中,我简单的介绍了 redux 的基础内容,本篇文章中,我们将再度深入 redux。
redux 解决的问题

数据和函数的层层传递
多个组件同时修改某全局变量

一、react 数据流

众所周知,react 的单向数据流是这样的,父组件可以向子组件传递数据我们通常用过状态提升将数据存于高阶函数中,使我们的子组件尽可能的更 ” 纯 ”,更好的实现代码复用。
可能在页面结构简单的小型项目中我们还没觉得有什么不妥,但是倘若在页面结构稍复杂的项目中,就会变成这样 D 组件中的数据存于 Container 中,要通过 Container -> Content -> B -> D 才能到达 D 组件。当然,这对我们聪明有能干的开发者们并不算什么,耗些时间也能刚出来。
Then,这种页面,你还能搞得定吗?就算你能搞定,你的代码中也有大量的冗余,从 Container 到 N 之间的所有组件都要传递 N 需要的 props
所以,为了解决层层传递,react-redux 就出现了它利用了 react 中的 context,在 Container 的 context 里创建 store,使 Container 的所有子组件,孙组件等等都可以直接获取 store 中的内容。

二、修改 store
我曾在快速理解 redux 中提起,为了解决模块(组件)之间需要共享数据 和 数据可能被任意修改导致不可预料的结果 的矛盾,redux 团队创建了 dispatch。So 不可预料的结果究竟是什么?
我们思考一个问题,假如所有的组件都以 store.xxx = xxx; // 伪代码 这种方式修改全局变量,会引发什么问题?
我们再思考,为何 python 等语言会存在线程锁,数据库也存在锁,操作系统的生产者 / 消费者问题等等假如 A 和 B 同时修改 store,store 是遵从 A 还是遵从 B?
为了避免以上情况引发死锁 redux 想出了一个办法:封装一个 dispatch 函数,接收一个 action 对象作为参数,每当组件想要修改 store 时必须给 dispatch 传递 action,然后再 store 内部根据 action 对象的 type 将 dispatch 分发到相应的队列中,每一时刻仅执行一个 dispatch
三、redux 异步问题
思考这样一个情景,我们从后端的接口获取了数据,我们想将其存入 store 中。但是当执行到 reducer 时,数据是否已经获取到?假如没有,又该怎么办?就在此时,中间件出现了,例如 redux-saga, redux-thunk 等等。

redux-saga 使用了 generate 生成器,使开发者可以按同步思路的书写异步代码,再根据 action 的 type 选择相应 reducer 更新 store
function *fetchNodeDetailByNodeId({payload: { nodeId} }, {call, put}) {
try {
const {data, status}= yield call(fetchNodeDetailByNodeId, nodeId)
if (data && status.errmsg === ‘success’) {
yield put({
type: ‘setStates’,
payload: {
nodeDetailData: data,
},
});
} else {
message.info(‘ 开了个小差, 再试一次吧..’);
}
} catch (error) {
console.log(error);
}
},

退出移动版