Home > Web Front-end > JS Tutorial > How to Update a Nested Object within State in React Using setState?

How to Update a Nested Object within State in React Using setState?

Barbara Streisand
Release: 2024-11-02 07:07:02
Original
1040 people have browsed it

How to Update a Nested Object within State in React Using setState?

How to Update an Object within a Nested State Using setState in React

In React, it's common to encounter nested state objects that require targeted updates based on user inputs. Consider the following code snippet:

var DynamicForm = React.createClass({
  getInitialState: function() {
   var items = {};
   items[1] = { name: 'field 1', populate_at: 'web_start',
                same_as: 'customer_name',
                autocomplete_from: 'customer_name', title: '' };
   items[2] = { name: 'field 2', populate_at: 'web_end',
                same_as: 'user_name', 
                    autocomplete_from: 'user_name', title: '' };

     return { items };
   },

  render: function() {
     var _this = this;
     return (
       <div>
         { Object.keys(this.state.items).map(function (key) {
           var item = _this.state.items[key];
           return (
             <div>
               <PopulateAtCheckboxes this={this}
                 checked={item.populate_at} id={key} 
                   populate_at={data.populate_at} />
            </div>
            );
        }, this)}
        <button onClick={this.newFieldEntry}>Create a new field</button>
        <button onClick={this.saveAndContinue}>Save and Continue</button>
      </div>
    );
  }
});
Copy after login

In this component, the state consists of a nested object, items, which contains items indexed by their position. However, the goal is to update a specific item within the items object upon user interaction.

var PopulateAtCheckboxes = React.createClass({
  handleChange: function (e) {
     item = this.state.items[1];
     item.name = 'newName';
     items[1] = item;
     this.setState({items: items});
  },
  render: function() {
    var populateAtCheckbox = this.props.populate_at.map(function(value) {
      return (
        <label for={value}>
          <input type="radio" name={'populate_at'+this.props.id} value={value}
            onChange={this.handleChange} checked={this.props.checked == value}
            ref="populate-at"/>
          {value}
        </label>
      );
    }, this);
    return (
      <div className="populate-at-checkboxes">
        {populateAtCheckbox}
      </div>
    );
  }
});
Copy after login

While the above approach attempts to update the state, it's not the recommended way to mutate nested state objects in React. To ensure immutability and prevent unwanted side effects, the correct approach is to create a shallow copy of the state object, then modify the copy and finally set the state to the modified copy.

handleChange: function (e) {
    // 1. Make a shallow copy of the items
    let items = [...this.state.items];
    // 2. Make a shallow copy of the item you want to mutate
    let item = {...items[1]};
    // 3. Replace the property you're interested in
    item.name = 'newName';
    // 4. Put it back into our array. N.B. we *are* mutating the array here, 
    //    but that's why we made a copy first
    items[1] = item;
    // 5. Set the state to our new copy
    this.setState({items});
},
Copy after login

Alternatively, if you prefer a more concise approach, you can use the spread syntax to achieve the same result in one line:

this.setState(({items}) => ({
    items: [
        ...items.slice(0,1),
        {
            ...items[1],
            name: 'newName',
        },
        ...items.slice(2)
    ]
}));
Copy after login

The above is the detailed content of How to Update a Nested Object within State in React Using setState?. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template