简体   繁体   English

状态正在改变着我

[英]State is changing on me inside mutation

I am having a really weird issue with state changing inside a mutation(!). 我遇到一个非常奇怪的问题,即突变(!)中的状态改变。 In my mutation I am logging the following on the first two lines: 在我的变异中,我在前两行记录以下内容:

console.log('mutation state:', state)
console.log('mutation state.game.gameTree[2]:', state.game.gameTree[2]) 

Expected: that state.game.gameTree is the same 预期: state.game.gameTree相同

Actual: They are not! 实际:不是! As you can see on the screenshot state.game.gameTree[2].activeActionId are not the same. 如您在屏幕快照上看到的, state.game.gameTree[2].activeActionId不相同。

控制台日志

How can this value possibly change from line 1 to line 2? 该值如何从第1行更改为第2行? I hope someone can help :) 我希望有人能帮帮忙 :)

Chrome displays the value of an object at the time you view it in the console, not at the time it is logged. Chrome浏览器会在您在控制台中查看对象时显示该对象的值,而不是在记录该对象时显示它的值。 I would try doing this: 我会尝试这样做:

console.log('mutation state:', JSON.parse(JSON.stringify(state)))
console.log('mutation state.game.gameTree[2]:', JSON.parse(JSON.stringify(state.game.gameTree[2])))

And if you still get the same issue, then something weird is going on. 如果仍然遇到相同的问题,则说明发生了一些奇怪的事情。

For example, if you had: 例如,如果您有:

 function example() { var a = { b: { c: 1 }}; return function() { abc++; return a; } } var wtf = example() console.log(wtf()) console.log(wtf()) console.log(wtf()) 

You'll see here that it increments as expected. 您会在这里看到它按预期增加。 If you run it in chrome, you'll see: 如果您在chrome中运行它,则会看到:

{b: {…}}
{b: {…}}
{b: {…}}

and when you then expand it, they would all show the same value. 然后当您展开它时,它们都将显示相同的值。

As dave already mentioned, if you hover over the i to the right of your expanded object, you will see that "it has been evaluated now". 正如戴夫已经提到的那样,如果将鼠标悬停在扩展对象右侧的i上,您将看到“它已被评估”。 In other words, it will check what the value is at the time you expand it, not what the value is when it was logged. 换句话说,它将在扩展时检查该值是什么,而不是记录该值时的值。

If you need to debug something that is changing rapidly, use a debugger statement. 如果您需要调试快速变化的内容,请使用debugger语句。 This will pause execution and shows the debugger statement in your source. 这将暂停执行并在您的源代码中显示调试器语句。 You can hover over variables to see their content, or find a variable in some scope on the right hand side. 您可以将鼠标悬停在变量上以查看其内容,或在右侧的某个范围内找到变量。 You can step through your code to see how your variables change. 您可以单步执行代码以查看变量如何变化。 If you log something, since the execution has stopped, the object will actually be evaluated at the time it was logged if you do: 如果您记录了一些内容,则由于执行已停止,因此您将在记录对象时对对象进行实际评估:

console.log(x);
debugger;

I found the cause. 我找到了原因。 Thank you both for your suggestions. 谢谢你们的建议。 They were very helpful in guiding me in the right direction. 他们对指导我朝正确的方向很有帮助。

I was actually mutating the game object in a domain function that was expecting a simple data object. 我实际上是在期望简单数据对象的域函数中对游戏对象进行变异。 I have always considered my domain functions immutable since they all return new data objects using the spread operator. 我一直认为我的域函数是不可变的,因为它们都使用散布运算符返回新的数据对象。 And coming from a functional framework based on immutable reactive streams this had never been a problem. 来自基于不可变反应流的功能框架,这从来就不是问题。

However, with Vue I realize that this can be problematic since Game is not longer a plain data object. 但是,借助Vue,我意识到这可能会带来问题,因为Game不再是普通的数据对象。 I will have to look into how to deal optimally with this. 我将不得不研究如何对此进行最佳处理。

For now, using JSON.parse(JSON.stringify(state))) works. 目前,可以使用JSON.parse(JSON.stringify(state)))。 It converts game to a plain data object and everything works as expected. 它将游戏转换为纯数据对象,并且一切正常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM