面试官叫我手写 Redux - 3

965 阅读2分钟

前篇 juejin.cn/post/694268…


方:上回说到我们在 connect 里让每个 Wrapper 监听 store 的变化,以保证只有 connect 过的组件会在 store 变化时 render

学生:今天讲什么?

方:今天讲如何让组件「只在自己依赖的数据变化时重新 render」。

学生:上次说加 selector 可以搞定

方:没错,不过今天加的代码稍稍有点多

这样一来,每个组件都可以在 connect 的时候,选择自己在什么数据变化的时候更新了。

学生:原来如此。

方:同样的思路,我们可以给 connect 加上 mapDispatchToProps 参数:

学生:确实。

方:现在看看我们的 redux,还有什么没有封装:

学生:你的 appContext.Provider 跟 Redux 的 Provider 还不是完全一致

方:那我们就封装一下:

然后就看起来一样啦:

学生:reducer 在哪定义的呢?

方:目前是写死在 redux.js 里的,我们需要让用户传入 reducer,所以我们提供一个 configureStore 给用户,用于传入 reducer 和初始 state:

configureStore 的用法如下:

学生:哇,现在跟 Redux 就已经非常像了。

方:是的。我们来总结一下目前我们自己写的 Redux 的思路:

  1. 提供 configureStore 让用户传入 store.reducer 和 store.state
  2. 提供 Provider 让用户划定全局 state 的作用范围
  3. 提供 connect 让组件被 Wrapper 接管
  4. 让 Wrapper 根据 selector 来获取局部的 state 并传给组件
  5. 让 Wrapper 根据 dispatchSelector 来获取对 dispatch 的封装,并传给组件
  6. 让 Wrapper 通过 store.subscribe 来监听 state 的变化,一旦自己依赖的 state 变化就强制 render 自己
  7. 组件可以从 props 里获取局部 state 以及 dispatch 的封装
  8. 组件调用 dispatch 后,会通过 reducer 获取 newState,以替换旧的 state

大概就是这些。最终代码:determined-framework-gvhg1 - CodeSandbox

学生:确实不难,但是面试官问我的时候我怎么想不到呢?

方:自己想不出来就先模仿,模仿多了就能自己想出来了。

学生:好的,谢谢你

本文告一段落,后续预告:

  1. Redux 的中间件怎么写?
  2. Redux-thunk 是什么?
  3. Redux-sage 是什么?
  4. dva.js 是什么?