第165期:我们为什么使用React Redux

436 阅读5分钟

封面图

image.png

颇有一种《桃花源记》的感觉。

晋太元中,武陵人捕鱼为业,缘溪行,忘路之远近,忽逢桃花林,夹岸数百步,中无杂树,芳草鲜美,落英缤纷。

image.png

园中有一小台,四角挂有风铃,微风轻拂,铃声清脆悦耳。

周五时,趁着中午的时间,和同事一起逛了下上班附近的一个小园子,颇有几处风景。

为什么我们要使用 React-Redux

Redux 它自己本身就是一个独立的状态库,它可以在任何UI框架中使用,比如:React, Angular, Vue, Ember, 以及 vanilla JS,尽管 Redux 通常和 React一起使用,他们其实是相互独立的。

如果我们正在任意一种UI框架中使用Redux,我们通常需要用一种UI绑定的库来将Redux和我们使用的UI框架绑定到一起,而不是从我们的UI的代码中直接操作store状态。

React-Redux其实就是官方的ReduxUI绑定库。所以,当我们在React和Redux的时候,我们也需要使用React-Redux将这两个库绑定到一起。

While it is possible to write Redux store subscription logic by hand, doing so would become very repetitive. In addition, optimizing UI performance would require complicated logic.

虽然可以手工编写Redux的状态订阅的逻辑,但这样做是一项需要重复的工作。此外,优化UI的性能还需要复杂的逻辑。

订阅状态、检查数据的更新以及触发re-render的过程可以变得更加通用和可重用。React Redux这样的UI绑定库可以处理状态交互的逻辑,所以我们不需要自己动手编写相关的代码。

为什么我的组件没有重新渲染,或者我的mapStateToProps没有运行?

意外地直接更改或修改状态是组件在调度操作后不重新渲染的最常见原因。

Redux希望我们的reducers能够“免疫”地更新其状态,这实际上意味着始终复制我们的数据,并将我们的更改应用于副本。

如果我们从reducer返回相同的对象,则Redux会认为没有任何更改,即使您对其内容进行了更改。

类似地,React Redux试图通过在shouldComponentUpdate中对传入的道具进行浅相等引用检查来提高性能,如果所有引用都相同,则shouldComponentUpdate返回false以跳过实际更新原始组件。

我们要记住的重要的一点是,无论何时更新嵌套值,都必须在状态树中返回它上面的值的新副本。

比如我们有一个 state.a.b.c.d, 我们希望对 d做一个更新,我们也需要返回一个新cba以及 state的副本 。

这也是我们通常在reducers中使用Object.assign()的原因。

为什么我的组件频繁重新渲染?

React Redux做了一些优化来保证我们的组件仅在需要时进行重新渲染。

其中一点是对传递给连接的mapStateToPropsmapDispatchToProps参数生成的组合props对象进行浅相等检查。但是,在每次调用mapStateToProps时都会创建新的数组或对象实例的情况下,浅相等并没有帮助。例如:

const mapStateToProps = state => {
  return {
    objects: state.objectIds.map(id => state.objects[id])
  }
}

尽管数组每次可能包含完全相同的对象引用,但数组本身是不同的引用,因此浅相等性检查失败,React Redux将重新渲染封装的组件。

额外的重新渲染可以通过使用reducer将对象数组保存到状态,使用Reselect缓存映射的数组,或者手动在组件中实现shouldComponentUpdate,并使用_.isEqual等函数进行更深入的道具比较来解决。

如何让mapStateToProps执行的更快

虽然React Redux确实可以最大限度地减少调用mapStateToProps函数的次数,但确保mapStateToProps快速运行并最大限度地降低其工作量仍然是一个好的方法。常见的推荐方法是使用Reselect创建记忆化的“选择器”函数。这些选择器可以组合在一起,并且稍后在管道中的选择器只有在其输入发生更改时才会运行。这意味着您可以创建一些选择器来执行过滤或排序等操作,并确保只有在需要时才能进行真正的工作。

Reselect是一个工具库。有兴趣的话可以了解一下。

为什么我的组件中没有this.props.dispatch

connect()函数接受两个主参数,这两个参数都是可选的。第一个是mapStateToProps,它是我们提供的一个函数,用于在存储更改时从存储中提取数据,并将这些值作为道具传递给组件。第二个是mapDispatchToProps,它是我们提供的一个函数,用于利用storedispatch功能。

如果在调用connect()时没有提供自己的mapDispatchToProps函数,React Redux将提供一个默认版本,它只是将dispatch函数作为prop返回。这意味着,如果您确实提供了自己的功能,则不会自动提供dispatch。如果您仍然希望它作为prop可用,则需要在mapDispatchToProps实现中显式地自己返回它。

如何将有限的社会资源和货币进行分配?

这是前天做了个梦,好像是不知怎么的到了教室里,然后被老师问了这么个问题,似乎给的回答是:社会资源和货币本质上都属于社会生产资料,我们只需要将有限的生产资料进行按需分配即可,这种形式就是计划经济。同理我们可以将社会生产资料交给市场来分配,这就形成了市场经济以及市场经济和计划经济相结合