【问题标题】:How to update the single property from array of object using setState (with a class component)?如何使用 setState(带有类组件)从对象数组中更新单个属性?
【发布时间】:2019-06-14 06:19:15
【问题描述】:

我在 this.state 中有一个对象数组,我正在尝试更新对象数组中的单个属性。

这是我的对象

 this.state = {
  persons: [
    { name: "name1", age: 1 },
    { name: "name2", age: 2 },
    { name: "name3", age: 3 }
  ],
  status: "Online"
};

我尝试更新 people[0].name

import React, { Component } from "react";     
class App extends Component {
      constructor() {
        super();
        this.state = {
          persons: [
            { name: "John", age: 24 },
            { name: "Ram", age: 44 },
            { name: "Keerthi", age: 23 }
          ],
          status: "Online"
        };
      }
      changeName() {
        console.log(this);
        this.setState({
         persons[0].name: "sdfsd"
        });
      }

      render() {
        return (
        <button onClick={this.changeName.bind(this)}>change name</button>
        );
      }
    }

我遇到了一个错误。

【问题讨论】:

  • 如果您可以展示更多代码或示例,那将是理想的,因为使用这个 sn-p 代码,我们没有太多信息......
  • @john_ny 你为什么选择这个答案?

标签: reactjs react-native redux react-redux react-hooks


【解决方案1】:

你应该编码:

let persons = [...this.state.persons]
persons[0].name= "updated name"
this.setState({ persons })

【讨论】:

    【解决方案2】:

    使用点运算符我们可以做到这一点。

        let persons = [...this.state.persons]
    persons[0].name= "updated name"
    this.setState({ persons })
    

    【讨论】:

    • 为什么这个和我的答案一样的新答案被接受了?
    【解决方案3】:

    你改变组件状态的问题,下面是不可变改变的例子,我建议你阅读关于如何改变反应状态的文章。或者你可以尝试使用 Mobx,因为它支持可变性

    changePerson(index, field, value) {
      const { persons } = this.state;
    
      this.setState({
        persons: persons.map((person, i) => index === i ? person[field] = value : person)
      })
    }
    
    // and you can use this method 
    this.changePerson(0, 'name', 'newName')
    

    【讨论】:

      【解决方案4】:
      this.setState(state => (state.persons[0].name = "updated name", state))
      

      【讨论】:

        【解决方案5】:

        假设一些条件检查来找到所需的人。

        const newPersonsData = this.state.persons.map((person)=>{
            return person.name=="name1" ? person.name="new_name" : person);
                              //^^^^^^^ can be some condition
        });
        
        this.setState({...this.state,{person:[...newPersonsData ]}});
        

        【讨论】:

          【解决方案6】:

          我认为最好的方法是先将状态复制到临时变量中,然后在更新该变量后使用 setState

          let personsCopy = this.state.persons
          personsCopy [0].name= "new name"
          this.setState({ persons: personsCopy  })
          

          【讨论】:

            【解决方案7】:

            我会这样做。

            看看这是否适合你。

            class App extends React.Component {
              constructor(props) {
                super(props);
                this.state = {
                  persons: [
                    { name: "John", age: 24 },
                    { name: "Ram", age: 44 },
                    { name: "Keerthi", age: 23 }
                  ],
                  status: "Online"
                };
                this.changeName = this.changeName.bind(this);
                this.changeAge = this.changeAge.bind(this);
              }
              
              changeName(value,index) {
                this.setState((prevState)=>{
                  const aux = prevState.persons;
                  aux[index].name = value;
                  return aux;
                });
              }
              
              changeAge(value,index) {
                this.setState((prevState)=>{
                  const aux = prevState.persons;
                  aux[index].age = value;
                  return aux;
                });
              }
                
                render() {
                  const personItems = this.state.persons.map((item,index)=>
                    <React.Fragment>
                      <input value={item.name} onChange={(e)=>this.changeName(e.target.value,index)}/>
                      <input value={item.age} onChange={(e)=>this.changeAge(e.target.value,index)}/>
                      <br/>
                    </React.Fragment>
                  );
                  
                  return(
                    <React.Fragment>
                      {personItems}
                      <div>{JSON.stringify(this.state.persons)}</div>
                    </React.Fragment>
                  );
                  
                }
            }
            
            ReactDOM.render(<App/>, document.getElementById('root'));
            <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
            <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
            <div id="root"></div>

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2022-01-02
              • 2020-03-29
              • 1970-01-01
              相关资源
              最近更新 更多