简体   繁体   中英

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)

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. This is weird to me because the console logs this.state.field[x] correctly.

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

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] .

Updater function should be used if updated state uses previous state. 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.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.

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

I have also created a codeSandbox demo to demonstrate my point. Hope it helps. Happy Coding :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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