为什么使用redux进行不可变状态

时间:2016-09-06 08:04:57

标签: redux

我正在学习redux并且正在努力理解为什么国家必须是不可改变的。你能否提供一个例子,最好在代码中,打破不可变合同导致不那么明显的副作用。

3 个答案:

答案 0 :(得分:10)

Redux最初是为了展示"时间旅行调试的想法而发明的。 - 能够在调度操作的历史记录中来回切换,并查看每个步骤中UI的外观。另一个方面是能够实时编辑代码,重新加载代码,并在给定新的reducer逻辑的情况下查看输出结果。

为了能够在状态之间来回切换,我们需要确保减速器功能没有副作用。这意味着需要不可变地应用数据更新。如果reducer函数实际上直接修改了它的数据,那么在状态之间来回踩踏将导致应用程序以意想不到的方式运行,并且将浪费调试工作。

此外,React-Redux库依赖于浅等式检查来查看组件的传入数据是否已更改。如果数据引用相同,则connect生成的包装器组件假定数据未更改,并且组件不需要重新呈现。不可变数据更新意味着创建了新的对象引用,因此@if (Model.InvoiceStatus == "NEW") { using(Html.BeginForm("Delete", "Invoices", new { InvoiceID = Model.InvoiceID, @returnUrl = Url.Action(ViewContext.RouteData.Values["action"].ToString()) }, FormMethod.Post)) { <!-- Your form elements goes here --> } } 将看到数据已更改且UI需要更新。

答案 1 :(得分:6)

两个想法

您需要了解有关不变性的两个想法:

  • 仅在reducers中改变状态
  • 使用不可变数据结构

仅在reducers

中改变状态

Redux尝试确保您只改变Reducers中的状态。这很重要,因为它更容易考虑您的应用程序数据流。

假设某个值未按预期显示在UI中,或者应更改的值仍显示其原始值。

在这种情况下,您可以考虑哪个减速器导致突变,看看出了什么问题。

这使得思考Redux问题非常简单,并使开发人员的工作效率很高。

有时你可能会错误地改变视图或动作中的状态。如果你想一想生命周期:

Action -> Reducer -> Views-> Action 

如果状态在视图中更改,然后触发操作,则可以覆盖状态更改。这将很难找到开发人员正在发生的事情。我们只通过在reducers中改变状态来解决这个问题。

  

注意:另一个好处是reducers是纯函数,所有异步函数都在actions / middleware中。因此,所有副作用都发生在动作/中间件层中。动作是我们与外部世界的连接(HTTP,本地存储等)。

使用不可变数据结构

正如我已经提到的,有时你可能会错误地改变视图或动作中的状态。为了减少这种情况发生的可能性,我们可以通过使用和不可变数据结构使状态突变显式化。

使用不可变数据结构也有performance benefits因为我们不需要执行深度相等检查来检查突变。

最常用的不可变数据结构提供程序是immutable.js

答案 2 :(得分:0)

我认为关键思想是

  • 易于重播任何给定的情况/测试流程-您可以从相同的初始状态开始以相同的操作重播
  • 快速重新呈现组件-由于引用已更改而不是其值,因此测试更改要快得多

当然,还有其他方面,我建议this nice article对其进行更详细的说明。