简体   繁体   English

将状态与来自循环反应的对象合并

[英]Merging state with object from loop react

This is in react and es2015 and I haven't put the import and call to the different .js files, but if you read it through they are calling each other fine. 这是在react和es2015中,我还没有将导入和调用放到不同的.js文件中,但是如果您通过阅读它们,它们会相互调用。

So I want to change the state on a key, whos value is an empty object. 所以我想更改键的状态,谁的值是一个空对象。 I have tried that and it works fine. 我已经尝试过了,效果很好。 Now I need to merge another object with empty object in state. 现在,我需要将另一个对象与状态为空的对象合并。 That I need to do from a function being called from a loop in a function, that's being called from a map-function. 我需要从一个函数中的一个循环中调用一个函数,这是从一个map函数中调用。 I get the proper object to the last function, but when I try to add every key-value set to the object in state, there only comes one set out, where I expected three. 我将适当的对象添加到最后一个函数,但是当我尝试将每个键值集添加到状态中的对象时,只会列出一个,我期望其中的三个。 I will try to clarify with some code. 我将尝试用一些代码来阐明。 I am trying to simplify the code, so If I am missing anything vital let me know. 我正在尝试简化代码,所以如果我错过了重要的事情,请告诉我。 (sorry for the names) (对不起名字)

Everything underneath is triggered onClick 下方的所有内容都会触发onClick

//item.js
[...]
let title = this.props.title;

someArrayWithObjs.map(function(item, key) {
  checkProcess(title);
})

This parts works fine as far as I can tell 据我所知,这部分工作正常

//yet.js
[...]
constructor(props) {
 super(props);
 this.state = {vitalObj: {}}
}

checkProcess(title) {
let importantObj = {};

for (let value in needValue) {
  if (needValue[value] <= presentLvl[value]) {
    importantObj[title] = true;
  } else {
    importantObj[title] = false;
    return makeRenderObj(importantObj);
  };
 }
return makeRenderObj(importantObj);
}

This also seems to give me the result I want, but then tricky parts come. 这似乎也给了我想要的结果,但是棘手的部分来了。 I want something like: 我想要类似的东西:

makeRenderObj(importantObj) {
 let vitalObj = this.state.vitalObj;

  console.log(importantObj);
 let together = React.addons.update(importantObj, {$merge: vitalObj});
  console.log(together);

this.setState({vitalObj: together});
}

I read somewhere I might be mutating state, that's why I have tried immutable. 我在某个地方可能正在改变状态的地方读过书,这就是为什么我尝试不可变的原因。 I can't remember precise what I tried before, so I won't confuse with writing a bad example. 我不记得我之前尝试过的内容是否精确,因此我不会混淆编写一个不好的例子。

The last two console.logs give me this output, 1. click 最后两个console.logs给我这个输出,1.单击

 {key1: correctValue} //good
 {key1: correctValue} //good
 {key2: correctValue} //good
 {key2: correctValue} //why not key1 as well?
 {key3: correctValue} // good
 {key3: correctValue} //and again ??

And this on the second click 然后第二次点击

 {key1: correctValue} //good
 {key3: correctValue, key1: correctValue} //??
 {key2: correctValue} //good
 {key3: correctValue, key2: correctValue} //??
 {key3: correctValue} // good
 {key3: correctValue} //??

So I am receiving the proper objects with the right keys and the right values, but I am merging them wrong - at least that's what I think. 因此,我收到具有正确键和正确值的适当对象,但我将它们错误合并-至少我是这样认为的。

I would like to know, why this is happening, and possibly how I can rewrite it? 我想知道为什么会这样,并且可能如何重写它?

setState is sometimes asynchronous (sort of), so running a bunch in a loop isn't going to let you operate on the most recent value with each iterations. setState有时是异步的(某种程度上),因此在循环中运行一堆束不会让您每次迭代都使用最新值。 Because this.state isn't immediately updated when you call this.setState. 由于this.state并不会立即更新,当你调用this.setState。 Luckily setState has another signature for dealing with this case. 幸运的是, setState还有另一个用于处理这种情况的签名。

setState((incrementalState)=> {
  let vitalObj = incrementalState.vitalObj;
  let together = React.addons.update(importantObj, {$merge: vitalObj});
  return { vitalObj: together }
})

Essentially passing a function means that each function will be called incrementally (maybe later) but in order so each iteration of you loop is working with the sstate from the last iteration 从本质上讲,传递函数意味着将逐步(可能稍后)调用每个函数,但为了使循环的每次迭代都使用上一次迭代的sstate进行操作

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

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