Kavin Mukil
Kavin Mukil

Reputation: 3

How to update key/value of a nested state object (React JS)

I am trying to update a key/value pair of a nested object in the state while the user types in the form. My state looks like this :

constructor(props) {
super(props);
this.state = {
  details: {
    detail1: {
      title: "",
      description: "",
      image1: null,
      image2: null,
    },
    detail2: {
      title: "",
      description: "",
      image1: null,
      image2: null,
    },
   detail3: {
      title: "",
      description: "",
      image1: null,
      image2: null,
    },
  },
};

}

This is my render method :

<form>
      <input
        type="text"
        value={this.state.creatives.creative1.title}
        onChange={(e) => {
          this.setState((prevState) => ({
            creatives: {
              ...prevState.creatives,
              creative1: {
                ...prevState.creatives.creative1,
                title: e.target.value,
              },
            },
          }));
          console.log(this.state.details.detail1.title);
        }}
      ></input>
    </form>

I have tried to update the key/value as above in the onChange method, but the console says that I cannot call .target on null. For some reason, The event.target returns null, I am not sure why. If anyone has a better solution to add the value typed to update the state, please do help.

Upvotes: 0

Views: 766

Answers (1)

BerndS
BerndS

Reputation: 409

The event passed to onChange is a Synthetic Event. You can't use such an event in an asynchronous way as React will reuse the event. setState calls the updater function in an asynchronous way. If you store the event value in a constant and access that in setState, it should work.

https://reactjs.org/docs/events.html

https://reactjs.org/docs/react-component.html#setstate

onChange={(e) => {
   const value = e.target.value
   this.setState((prevState) => ({
       creatives: {
          ...prevState.creatives,
          creative1: {
            ...prevState.creatives.creative1,
            title: value,
          },
        },
      }));
      console.log(this.state.details.detail1.title);
    }}

Upvotes: 1

Related Questions