简体   繁体   中英

React setState of Array inside object ES6

I am new to Javascript so probably I am lacking the fundamentals to solve this issue. I am trying different things, and reading tutorials, but so far no luck.

The objective is to modify the state, just by addding a new keyword to the array "keywords" that is contained inside the "blockOptions" object. I add a key/value for then using .map() or deleting the keyword if needing. I am also trying to use ES6 recommendations.

Here is the constructor:

      blockOptions: {
          ...
          keywords: [],

And here is the function I call from the component

 onAddKeyword(e) {
    if (e.key === "Enter") {
      var newKeyword = {
        text: e.target.value,
        key: Date.now()
      };

      this.setState({
        blockOptions.keywords: [...this.state.blockOptions.keywords, newKeyword]
      });

      console.log(this.blockOptions.keywords);
      e.target.value = "";
      e.preventDefault();
    }
  }

If I use this same code with an array that is not nested inside "blockOptions", everything works fine. Any suggestion about the code itself would be valuable as I am still new to JS.

Thanks for your help

The first issue in your code is that you supposse

{
    blockOptions.keywords: []
}

works as a sort of shortcut for

{
     blockOptions: {
          keywords: []
     }
}

The left-side on a literal object creation must be only a String or a Symbol , your example should throw an Uncaught SyntaxError: Unexpected token : .

Besides that, you'll need to do something like:

this.setState({
    blockOptions: {
        ...this.state.blockOptions, //copy all the properties
        keywords: [...this.state.blockOptions.keywords, newKeyword]
    }
})

The gather / ... operator on Objects, is not an ES2015 feature, but its available through babel.

A native ES2015 alternative is

const blockOptionsCopy = Object.assign(
   {},
   this.state.blockOptions,
   { keywords: [...this.state.blockOptions.keywords, newKeyword] }
);
this.setState({
   blockOptions: blockOptionsCopy
})
    const { blockOptions } = this.state;
    blockOptions.keywords.push(newKeyword);
    this.setState({ blockOptions });

You have to do it immutably and copy the whole object and inner array.

First copy the blockOptions using the spread operator. Then overwrite the keywords property with a new array:

this.setState({
  blockOptions: {
    ...this.state.blockOptions, // copy blockOptions
    keywords: [...this.state.blockOptions.keywords, newKeyword] // overwrite keywords
  }
});

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