优雅的使用redux

最近在做项目重构的时候,准备采用next js进行服务器端的渲染,在状态管理方面一直没有找出一个很好的方案,因为自己有以下的需求点:
1. 配置更加简单,少些模板化代码
2. 状态管理跟着路由走(next js)里无路由配置,可以说成是跟着模块走吧。
3. 更好的调试工具
期间考虑过以下几个状态管理方案
1. redux: redux设计的太重,actionType, action creator, reducer,异步处理等太过分散,虽然可以使用redux-action进行一些模板代码的编写工作,但是整个说来还是过于繁杂。
2. mobx: 挺好的状态管理工具用的人也比较多,但是一直对这种更改数据结构的库没有啥好感,毕竟是团队开发,所以数据结构这种东西应该要严格的进行规范。
3. dva: 重构前项目使用的就是dva1.x版本,感觉下来是挺不错的,因为商城项目也并不大,所以感觉整体用下来感觉还挺不错的。dva的动态化加载是跟着路由走的,所以对于next js来说不太适合。

所以就有了下面这篇文章,文章是翻译过来的。过段时间等项目重构完了,来说下感受吧!

重新设计 Redux

状态管理工具不是应该用来解决问题的吗? 直观的来说,开发者似乎知道这样一个事实: 状态管理似乎是比较难管理的. 在这篇文章中,我们探讨您可能会问自己的一些问题:

  • 您需要一个状态管理库吗?
  • 最流行的Redux库是否是值得采用的? 为什么选择,或者为什么不选择?
  • 我们是否能够制定一个更好的管理库哪,如果要做,应该如何做?

状态管理是否需要一个库?

作为一个前端仅仅只是调调样式; 真正的开发者应该知道在哪里存储你的状态. 简单的来说: 它是复杂的, 但又不是复杂的.

在使用基于组件的视图框架/库(如React)时,让我们看看我们的选项:

优雅的使用redux_第1张图片
image.png

1. Component state

存在于单个组件内的状态。 在 React中, 想想一下 statesetState更新.

2. Relative state

状态从父组件传到子组件. 在React中, 想想一下 props 作为一个属性从父组件传到子组件.

3. Provided State

状态保存在一个根的 provider中, 由组件下的 consumer访问而不管是否是接近的. 在React中, 想想一下 context API的使用过程.

很多的状态都在View中, 它影响着UI的显示. 但是影响着基础数据和逻辑的代码在哪里哪?

将所有的数据放在页面中会导致 separation of concerns: 它将你的javascript与你的试图联系在了一起, 这会导致代码比较难以测试, 最大的发恼是: 您必须不断思考和重新调整存储状态的位置.

由于设计发生变化并且通常很难分辨哪些组件需要哪种状态,因此状态管理变得复杂。最直接的选择是从根组件中提供所有状态,此时您可能最好只使用下面所说的管理方式。

4. External State

状态可以被移到视图层以外. 这个库可以用 “connect” 将 provider/consumer 链接,以保持同步.

也许最流行的状态管理库是Redux。在过去的两年里,它已经大受欢迎。那么为什么这么喜欢一个简单的库?

Redux性能更高吗? 不会。每次必须处理的新动作都会稍微慢一些。
Redux更简单吗? 当然不是.

那么为什么每个人不适用 global.state = {}?


为什么 Redux?

在内部,Redux实际上和根对象一样。

优雅的使用redux_第2张图片
image.png

在Redux中你不能直接修改状态. 唯一修改的办法是用: dispatch 发出一个 action 进入这个管道去更新状态.

管道中有两个监听器: middleware & subscriptions. 中间件可以监听到传入的action, 例如 “logger”, “devtools”, or a “syncWithServer” listener. Subscriptionsare 是用来将状态的更改广播出去.

最后, reducers 将状态更新分解到更小, 更模块化和更好管理的块.

Redux对开发者来说更加简单比使用一个全局状态来作为应用的状态来说。

将Redux作为一个一个状态到后一个状态的全局对象,以及到下一个状态的简化方法。


但Redux不是太复杂吗?(自己总结的痛点)

- 复杂的Api,和配置
- 不知道如何组织action, action creator, reducer
- 如何处理异步


重新设计Redux

我认为Redux值得重写。我带来了7个应该改进的地方。

1. 设置

让我看下最基本的设置 例子。

优雅的使用redux_第3张图片
image.png

在第一步之后许多的开发者是对这比较迷惑的. 什么是 thunk? compose? 一个方法可以 这些事吗?

Redux是否要基于组合配置. 最右侧的设置是不是更加友好.

2. 简化的 Reducers

Redux中的Reducers让我们远离不必要的切换语句。

优雅的使用redux_第4张图片
image.png

假设reducer与action类型匹配,我们可以反转params,这样每个reducer都是一个接受状态和动作的纯函数。也许更简单,我们可以标准化操作并仅传入状态和有效payload。

4. Async/Await over Thunks

Thunk通常用于在Redux中创建异步操作。在许多方面,thunk的工作方式似乎更像是一个聪明的黑客,而不是官方推荐的解决方案。

  1. 您调度一个动作,它实际上是一个函数而不是预期的对象。
  2. Thunk中间件检查每个动作以查看它是否是一个函数。
  3. 如果是这样,中间件调用该函数并传入一些存储方法的访问权限:dispatch和getState。

真的?对于简单的动作来说,作为对象,函数,甚至是Promise动态地键入是不是不好的做法?

优雅的使用redux_第5张图片
image.png

就像右边的例子,我们不能只是异步/等待吗?

5.两种行为

当你考虑它时,实际上有两种行为:

  1. Reducer action:触发​​reducer action并改变状态。
  2. Effect action:触发​​异步操作。这可能会调用Reducer操作,但异步函数不会直接更改任何状态。

区分这两种类型的操作会更有帮助,并且不会混淆上述用法与“thunks”。

6.没有Action Types作为变量

为什么以不同的方式对待action creator和reducer是标准做法?没有其他的存在吗?改变一个不影响另一个吗?

action creator和reducer是一枚硬币的两面。

const ACTION_ONE = 'ACTION_ONE'是action creator和reducer分离的副作用。将两者视为一体,不再需要导出类型字符串的文件。

7.作为action creator的reducer

通过使用Redux的元素进行分组,您可能会想出一个更简单的模式。

优雅的使用redux_第6张图片
image.png

( https://gist.github.com/ShMcK/6e8a7b576ffac1975ec2868c7816c37c)

可以从reducer中自动确定action creator。毕竟,在这种情况下,reducer可以成为action creator

使用基本命名约定,以下是可预测的:

  1. 如果reducer的名称为“increment”,则类型为“increment”。更好的是,让命名空间:count/increment。
  2. 每个操作都通过“payload”传递数据。
优雅的使用redux_第7张图片
image.png

现在count.increment我们可以从reducer生成动作action creator。


好消息:我们可以拥有更好的Redux

这些痛点是我们创建Rematch的原因。

优雅的使用redux_第8张图片
image.png

Rematch是Redux的包装器,它提供了一个更简单的API,而不会丢失任何可配置性。

优雅的使用redux_第9张图片
image.png

请参阅下面的完整Rematch示例:

优雅的使用redux_第10张图片
image.png

( https://gist.github.com/ShMcK/194360c2b54c2e55c1008a17e486510c)

在过去的几个月里,我一直在使用Rematch。作为见证,我会说:

我从来没有花太多时间思考状态管理。

Redux不会消失,也不应该消失。拥抱Redux背后的简单模式,学习曲线更少,样板更少,认知开销更少。

尝试rematch,看看你是不是喜欢它。

你可能感兴趣的:(优雅的使用redux)