如何在反应中正确更新状态

时间:2020-07-01 00:45:20

标签: javascript reactjs

我正在学习反应,我想尽一切办法,所以我尝试进行一些练习。 所以我决定从数组中删除一个元素。 所以这就是我想要做的: 当用户单击UI中的项目时,我使用该元素的索引将其删除并更新状态,这是我使用的代码。

    class App extends Component  {
    
         state={
            persons: [
              { id: 'asfa1', name: 'Max', age: 28 },
              { id: 'vasdf1', name: 'Manu', age: 29 },
              { id: 'asdf11', name: 'Stephanie', age: 26 },
            ],
        
            showPersons:false,
          }
          deletePersonsHandler=(index)=>{
        const persons= [...this.state.persons];
        persons.splice(index,1)
        this.setState({persons:persons.splice(index,1)});
        console.log(this.state)
        console.log(persons)
          } 
               this.state.persons.map((el,index)=>{
              return(
                <Person key={el.id} name={el.name} age={el.age} click={(index)=>{this.deletePersonsHandler(index)}}></Person>
              )
            }
}

正如您在deletePersonsHandler()中看到的那样,我从person数组创建了一个副本,然后立即更新状态,结果是单击的元素没有被删除,而是只停留在第一个元素,其余元素被删除,数组只有两个元素 无论我点击哪个元素

在我点击之前:

enter image description here

点击任意元素后

enter image description here

状态为

enter image description here

这是我新创建的人员数组:

enter image description here

通过使用以下代码设法解决问题的方式:

  deletePersonsHandler=(index)=>{
const persons= [...this.state.persons];
persons.splice(index,1)
this.setState({persons:persons});
  }

但是我想知道第一次尝试出了什么问题,为什么它没有按照我想要的方式工作,我仍然是一个初学者,请多多指教,并在此先感谢您。 注意:我还有另一个组成部分,即人员组成部分(我认为在此加入并不重要)

2 个答案:

答案 0 :(得分:1)

在第一次尝试中,您只是使用仅包含已删除元素的新数组副本设置状态。

this.setState({persons:persons.splice(index,1)});
// returns removed element

然后

const persons= [...this.state.persons];
persons.splice(index,1);
this.setState({persons:persons});

是在删除数组中的项目之后设置的元素。

查看所附图片

enter image description here

答案 1 :(得分:0)

除了App之外,您还应该创建另一个类,并添加构造函数,然后在其中声明状态。

class MyComponent extends React.Component{
  constructor() {
    super();
    this.state = {
      persons: [
        { id: 'asfa1', name: 'Max', age: 28 },
        { id: 'vasdf1', name: 'Manu', age: 29 },
        { id: 'asdf11', name: 'Stephanie', age: 26 }
      ],
      showPersons: false
    }
  }
}

在构造函数下方,您应该声明函数:

  deletePersonsHandler(index) {
    const persons = [...this.state.persons];
    persons.splice(index, 1);
    this.setState({ persons });
  }

但是然后您需要像这样绑定该方法

  constructor() {
    ...
    this.deletePersonsHandler = this.deletePersonsHandler.bind(this);
  }

最后将render函数添加到您的类中,例如:

class MyComponent extends React.Component {
  constructor() {
    super();
    this.state = {
      persons: [
        { id: "asfa1", name: "Max", age: 28 },
        { id: "vasdf1", name: "Manu", age: 29 },
        { id: "asdf11", name: "Stephanie", age: 26 }
      ],
      showPersons: false
    };
    this.deletePersonsHandler = this.deletePersonsHandler.bind(this);
  }

  deletePersonsHandler(index) {
    const persons = [...this.state.persons];
    persons.splice(index, 1);
    this.setState({ persons });
  }

  render() {
    return (
      <div>
        {this.state.persons.map((el, index) => {
          return (
            <Person
              key={el.id}
              name={el.name}
              age={el.age}
              click={() => {
                this.deletePersonsHandler(index);
              }}
            />
          );
        })}
      </div>
    );
  }
}

您可以检查此工作here