Redux原则似乎相互矛盾

Redux原则似乎相互矛盾,redux,Redux,也许有人可以向我解释这一点,但在我看来,这两个原则相互矛盾,这确实阻碍了我在学习Redux方面的进步 状态是只读的并且使用纯函数进行更改 State之后的第一行是只读的:“改变State的唯一方法…”。如果某个东西是只读的,那么它首先就不能被变异。即使在Egghead视频中,状态也总是标记为const,但仍然会发生改变,这与const的目的背道而驰 有人能向我解释一下,这些想法是如何不完全相反的吗?就Redux以外的世界而言,该州是只读的。可以将其视为已发生的应用程序事件(操作)的仅追加序列的视

也许有人可以向我解释这一点,但在我看来,这两个原则相互矛盾,这确实阻碍了我在学习Redux方面的进步

状态是只读的并且使用纯函数进行更改

State之后的第一行是只读的:“改变State的唯一方法…”。如果某个东西是只读的,那么它首先就不能被变异。即使在Egghead视频中,状态也总是标记为
const
,但仍然会发生改变,这与
const
的目的背道而驰


有人能向我解释一下,这些想法是如何不完全相反的吗?

就Redux以外的世界而言,该州是只读的。可以将其视为已发生的应用程序事件(操作)的仅追加序列的视图。您可以生成新的操作,这些操作将导致状态变得不同

当然,这是真实的世界,有些地方是可变的。正如里奇·希基(Rich Hickey)的名言:

“如果一棵树倒在树林里,它会发出声音吗?如果一棵纯净的树 函数对数据进行变异以生成一个不可变的值,可以吗?”~ @里奇基

但是,在实际可行的情况下,您编写应用程序时不需要直接修改内容。相反,您描述了您希望看到的更改(分派操作),并由一个框架(Redux)执行这些更改,使用您的缩减器一次创建存储的整个视图(状态),并通过React的
道具
,生成一个新视图


这是受到函数式反应式编程概念的启发。在这个范例中,所有函数都是纯函数,您通过表示“如果某个值发生了变化,您将如何处理它”来处理随时间变化的概念。从某种意义上讲,您将一个变量的整个过去和未来概念化为一个不可变函数,您只是碰巧还不知道它的未来。抱歉,如果这太哲学化了。

这没有矛盾,尽管这种混乱是可以理解的

考虑它的一个好方法是在React状态和Redux状态之间进行类比

在React中,您只能在
constructor()
getInitialState()方法中定义一次组件状态。从那时起,您总是将
this.state
视为只读,而从不将任何内容分配给
this.state
。要更改状态,请调用
this.setState()

Redux也是如此。您只需定义一次状态或状态的每个不同部分。通常称为
initialState
,并指定为减速器的
state
参数的默认值。将
状态
视为只读意味着永远不会覆盖或改变状态。更改状态的唯一方法是使用减速器的返回值

或者,简言之。。。 我认为你真正的障碍在于状态是可变的和只读的,所以让我更简洁地说:


CD-ROM是只读的,但我可以弹出CD并替换为另一张。

状态不是只读的,它是不可变的。正如在“不可变数据结构”中一样。你能链接到你正在阅读的文章吗?同样,来自MDN:“const声明创建了一个对值的只读引用。它并不意味着它所持有的值是不可变的,只是变量标识符不能被重新分配。”FYI@JoshBeam这里的只读意味着“状态对象”是不可变的。如果状态不可更改,那么我们就不再需要javascript了。这只是javascript对象。所以当你说将状态视为只读时,你的意思是你的应用程序只有一部分是这样处理的。仅仅通过观看“书呆子”的视频,我就可以看出,状态并不总是只读的。减速器可以执行以下操作:
返回状态+1
。甚至使用
对象。分配
。你仍然在改变状态。这不是只读的。这也使得CD-ROM的类比是错误的,因为您必须复制旧光盘上的内容,然后添加到新光盘上。我不喜欢吹毛求疵,但我仍然不认为这是只读的。我的意思是只
Object.assign
reducer有一个名为
state
的输入参数,它从不更改该参数,而是返回一个新状态。不管这是否基于旧的状态,这都无关紧要。从概念上讲,
返回状态+1
不同于
状态=状态+1
。正确使用,
Object.assign
读取并复制,不会覆盖。这就是只读的意思。所以,如果状态只对除Redux之外的所有对象只读,我不明白为什么不这样说。事实上,它一直是只读的。@StevenWade不知道该告诉你什么:)你可以在源代码中看到发生了什么,如day:。我认为你提出了一个公平的理由,文件可以更加明确。作者在这里很活跃,看起来是个通情达理的家伙。也许会在GitHub回购协议上公开一个问题?