简体   繁体   English

如何使用键或值中的变量设置反应状态

[英]How to set react state with variables in key or value

I actually figured out how to get the result I need, but I was hoping that someone could breakdown whats going on here and why the other more straightforward paths I tried didnt work. 我实际上想出了如何获得所需的结果,但是我希望有人可以弄清楚这里发生的事情,以及为什么我尝试过的其他更直接的方法行不通。

essentially I was needing to set some nested state at various levels using some variables(namely id of the element) 本质上,我需要使用一些变量(即元素的id)在各个级别上设置一些嵌套状态

so I tried this way 所以我尝试了这种方式

 handleClick = (e) => {
    var x = e.target.id
    console.log(this.state.fields[x])
   !this.state.fields[x].disabled ? this.setState({[this.state.fields[x].disabled]:true}) : this.setState({[this.state.fields[x].disabled]:false})
}

This for whatever reason creates a state object "false" at the top level. 无论出于何种原因,这都会在顶层创建状态对象“ false”。 This is weird to me because the console logs this.state.field[x] correctly. 这对我来说很奇怪,因为控制台正确记录了this.state.field [x]。

I also tried the same but with 我也尝试过相同的方法

setState({[this.state.fields.x.disabled]:true})

and

setState({[fields.x.disabled]:true})

both of which wouldnt compile. 两者都不会编译。 Not to mention I cant even figure out how to easily update nested state properties...Surely there is an easy way! 更不用说我什至不知道如何轻松地更新嵌套状态属性...当然有一种简单的方法!

Im pretty new to react so any explaination as to what the problems are here would be greatly appreciated. 我现在反应还很新,因此,如果您对这里的问题有任何解释,将不胜感激。 Ill post my solution(workaround) 不适当地发布我的解决方案(解决方法)

created a new object and popped it back in place 创建了一个新对象并将其弹回原位

i guess I would be ok with this except for the fact the fields is a pretty big dictionary as is(over 100 sub dicts) and copy and pasting that many entries sounds expensive 我想我会接受的,除了事实是,字段是一个相当大的字典,它是(超过100个副词)并复制和粘贴很多条目听起来很昂贵

seems like alot of work just to flip one boolean property 似乎只需要翻转一个布尔属性就可以完成很多工作

handleClick = (e) => {
    var x = e.target.id

   //console.log("...",this.state.fields[x].disabled)

    if(!this.state.fields[x].disabled) {
        var cat = Object.assign({},this.state.fields)
         cat[x].disabled = true;

        this.setState({fields:cat})
    }
}

fields.x accesses a property with 'x' name, it's not the same as fields[x] . fields.x访问名称为'x'的属性,它与fields[x]

Updater function should be used if updated state uses previous state. 如果更新状态使用以前的状态,则应使用Updater函数 State mutation should be generally avoided because this may result in unexpected behaviour. 通常应避免状态突变,因为这可能导致意外的行为。

It likely should be: 可能应该是:

setState(({ fields }) => ({
  fields: {
    ...fields,
    [x]: {
      ...fields[x],
      disabled: true
    }
  }
}));
// Assuming your state is like this: 
  state = {
    fields: {
      "fieldId-1": {
        disabled: false
      },
      "fieldId-2": {
        disabled: true
      }
    }
  };

So, you are basically passing value of ' this.state.fields['fieldId-1'].disabled === false ' here and actually doing this in your setState call: 因此,您基本上是在这里传递' this.state.fields ['fieldId-1']。disabled === false '的值,并实际上在setState调用中这样做:

   this.setState({false: false});

which definitely will create a new field in your state object at top level and same goes with rest of your cases. 肯定会在顶层的状态对象中创建一个新字段,其余情况也是如此。

If you want to update the nested property eg 'fieldId-1' , then one possible way would be by merging your changes gracefully using updater function. 如果要更新嵌套属性,例如'fieldId-1' ,则一种可能的方法是使用updater函数优雅地合并更改。

    this.setState(prevState => ({
      fields: {
        ...this.state.fields,
        [x]: { disabled: !prevState.fields[x].disabled }
      }
    }));
  };

I have also created a codeSandbox demo to demonstrate my point. 我还创建了一个codeSandbox 演示来演示我的观点。 Hope it helps. 希望能帮助到你。 Happy Coding :) 快乐编码:)

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

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