Whats the best way to update an object in an array in ReactJS?

前端 未结 4 1208
悲&欢浪女
悲&欢浪女 2020-11-22 10:56

If you have an array as part of your state, and that array contains objects, whats an easy way to update the state with a change to one of those objects?

Example, mo

相关标签:
4条回答
  • 2020-11-22 11:03

    Trying to clean up/ explain better how to do this AND what's going on.

    • First, find the index of the element you're replacing in the state array.
    • Second, update the element at that index
    • Third, call setState with the new collection
    import update from 'immutability-helper';
    
    // this.state = { employees: [{id: 1, name: 'Obama'}, {id: 2, name: 'Trump'}] } 
    
    updateEmployee(employee) {
        const index = this.state.employees.findIndex((emp) => emp.id === employee.id);
        const updatedEmployees = update(this.state.employees, {$splice: [[index, 1, employee]]});  // array.splice(start, deleteCount, item1)
        this.setState({employees: updatedEmployees});
    }
    

    Edit: there's a much better way to do this w/o a 3rd party library

        const index = this.state.employees.findIndex(emp => emp.id === employee.id),
              employees = [...this.state.employees] // important to create a copy, otherwise you'll modify state outside of setState call
        employees[index] = employee;
        this.setState({employees});
    
    0 讨论(0)
  • 2020-11-22 11:03

    You can do this with multiple way, I am going to show you that I mostly used. When I am working with arrays in react usually I pass a custom attribute with current index value, in the example below I have passed data-index attribute, data- is html 5 convention.

    Ex:

    //handleChange method.
    handleChange(e){
      const {name, value} = e,
            index = e.target.getAttribute('data-index'), //custom attribute value
            updatedObj = Object.assign({}, this.state.arr[i],{[name]: value});
          
      //update state value.
      this.setState({
        arr: [
          ...this.state.arr.slice(0, index),
          updatedObj,
          ...this.state.arr.slice(index + 1)
        ]
      })
      }

    0 讨论(0)
  • 2020-11-22 11:13

    I quite like doing this with Object.assign rather than the immutability helpers.

    handleCommentEdit: function(id, text) {
        this.setState({
          data: this.state.data.map(el => (el.id === id ? Object.assign({}, el, { text }) : el))
        });
    }
    

    I just think this is much more succinct than splice and doesn't require knowing an index or explicitly handling the not found case.

    If you are feeling all ES2018, you can also do this with spread instead of Object.assign

    this.setState({
      data: this.state.data.map(el => (el.id === id ? {...el, text} : el))
    });
    
    0 讨论(0)
  • 2020-11-22 11:16

    While updating state the key part is to treat it as if it is immutable. Any solution would work fine if you can guarantee it.

    Here is my solution using immutability-helper:

    jsFiddle:

      var update = require('immutability-helper');
    
      handleCommentEdit: function(id, text) {
        var data = this.state.data;
        var commentIndex = data.findIndex(function(c) { 
            return c.id == id; 
        });
    
        var updatedComment = update(data[commentIndex], {text: {$set: text}}); 
    
        var newData = update(data, {
            $splice: [[commentIndex, 1, updatedComment]]
        });
        this.setState({data: newData});
      },
    

    Following questions about state arrays may also help:

    • Correct modification of state arrays in ReactJS
    • what is the preferred way to mutate a React state?
    0 讨论(0)
提交回复
热议问题