Javascript 即使在卸载组件后,React复选框仍保持选中状态

Javascript 即使在卸载组件后,React复选框仍保持选中状态,javascript,reactjs,dom,checkbox,redux,Javascript,Reactjs,Dom,Checkbox,Redux,所以,我有一个带有复选框的项目列表,就像一个经典的todo应用程序一样 当我选择“Johnny”然后单击“Deleteselectedrecords”时,Johnny确实消失了。耶 但是,一旦约翰尼走了,蕾妮现在就被检查了 我没有点击蕾妮。我只点击了约翰尼,但一旦约翰尼被删除,蕾妮就被选中了。wtf 显然,在复选框DOM保持为checked的情况下,发生了一些事情,尽管我刚刚删除了复选框 我试图通过更新componentWillUnmount中的状态来解决这个问题,但没有成功 import

所以,我有一个带有复选框的项目列表,就像一个经典的todo应用程序一样

当我选择“Johnny”然后单击“Deleteselectedrecords”时,Johnny确实消失了。耶

但是,一旦约翰尼走了,蕾妮现在就被检查了

我没有点击蕾妮。我只点击了约翰尼,但一旦约翰尼被删除,蕾妮就被选中了。wtf

显然,在复选框DOM保持为checked的情况下,发生了一些事情,尽管我刚刚删除了复选框

我试图通过更新componentWillUnmount中的状态来解决这个问题,但没有成功

import React, {Component} from 'react';

class Person extends Component {

  constructor(props) {
    super(props);

    this.state = {
      checked: false
    }

    this.checkboxToggle = this.checkboxToggle.bind(this);
  }

  checkboxToggle() {
    this.setState({ checked: !this.state.checked }, () => {
      if (this.state.checked === false) {
        console.log("Checked should be FALSE");
      }
      else if (this.state.checked === true) {
        console.log("Checked should be TRUE");
        this.props.setForDelete(this.props.person._id);
      }
    });
  }

  componentWillUnmount() {
    this.setState({ checked: false });
  }

    render() {
        return (
          <div>
            <input type="checkbox" name="person" checked={this.state.checked} onChange={this.checkboxToggle} />
            {this.props.person.name} ({this.props.person.age})
          </div>
        );
    }
}

export default Person;
import React,{Component}来自'React';
类Person扩展组件{
建造师(道具){
超级(道具);
此.state={
勾选:假
}
this.checkboxToggle=this.checkboxToggle.bind(this);
}
checkboxToggle(){
this.setState({checked:!this.state.checked},()=>{
if(this.state.checked==false){
console.log(“Checked应为FALSE”);
}
else if(this.state.checked==true){
console.log(“Checked应为TRUE”);
this.props.setForDelete(this.props.person.\u id);
}
});
}
组件将卸载(){
this.setState({checked:false});
}
render(){
返回(
{this.props.person.name}({this.props.person.age})
);
}
}
出口违约人;
Person组件中的其他所有内容都工作正常。删除任何记录后,如何使所有复选框变为未选中状态

更新:这是PeopleList,一个包含所有人的组件

import React, { Component } from 'react';
import Person from './Person';

class PeopleList extends Component {

  constructor(props) {
    super(props);
  }

  componentWillUnmount() {
    this.props.resetSetForDeleteArr();
  }

  render() {
    return(
      <div>
        {this.props.people.map((person, i) => {
          return <Person key={i} person={person} setForDelete={this.props.setForDelete} />;
        })}
        <div onClick={() => this.props.deleteRecords()}>Delete Selected Records</div>
        <div onClick={() => this.props.resetSetForDeleteArr()}>Empty Array.</div>
      </div>
    );
  }

} // end class

export default PeopleList;
import React,{Component}来自'React';
从“./人”导入人;
类PeopleList扩展了组件{
建造师(道具){
超级(道具);
}
组件将卸载(){
this.props.resetSetForDeleteArr();
}
render(){
返回(
{this.props.people.map((person,i)=>{
返回;
})}
this.props.deleteRecords()}>删除所选记录
this.props.resetSetForDeleteArr()}>空数组。
);
}
}//结束类
导出默认联系人列表;

不要将数组索引用作键属性

键是唯一用于标识DOM元素的属性。如果键与以前相同,则在您的示例中,
0
React假定DOM元素表示与以前相同的内容,即使现在有另一个文本

因此React将而不是重新启动状态并更新选中的属性

使用一些独特的方式,例如:

<Person key={person + '_' + i} ...

尝试更改
联系人列表中的下一行

{this.props.people.map((person, i) => {
      return <Person key={person._id} person={person} setForDelete={this.props.setForDelete} />;
    })}
{this.props.people.map((person,i)=>{
返回;
})}

我认为您可能在状态和传递函数方面遇到了一些问题。我创建了一个示例,该示例使用简单的映射和过滤函数来模拟delete。如果我不得不猜测,您可能没有跟踪检查和删除了哪些数据,并且可能缓存了检查的值。正如您在下面的代码中所看到的,这里有几个建议,您可以实现这些建议,以使代码更简单:

  • 将人物保持为哑/叶组件,毕竟它只渲染 您的复选框,不要试图保持选中状态。(至少 删除卸载生命周期(通常不需要它)
  • 您可以使用
    上下文
    或者一个帮助您跟踪状态的库,mobx的实现相当简单
  • onClick={()=>this.props.deleteRecords()}>
    如果您不需要人员列表中的任何额外逻辑,那么onClick={this.props.deleteRecords.bind(this)}>
可能更像这样 查看此处并尝试运行它:

import React, {Component} from 'react';
import {render} from 'react-dom';

const Person  = ({person, setForDelete}) => (
          <div>
            <input type="checkbox" name="person" checked={person.checked} onChange={setForDelete.bind(this, person)} />
            {person.name}
          </div>
);


class PeopleList extends Component {

  render() {

    return(
      <div>
       {this.props.people.map((person, i) => {
         return <Person key={i} person={person} setForDelete={this.props.setForDelete} />;
       })}
       <div onClick={this.props.deleteRecords}>Delete Selected Records</div>
     </div>
    );
  }

} // end class

class App extends React.Component {

  constructor(props) {
    super(props)
    this.state = {people:[{id:1, name:'Cesar', checked:false},{id:2, name:'Jose', checked:false},{id:3, name:'Marbel', checked:false}]}
  }

  deleteRecords() {
    const people = this.state.people.filter(p => !p.checked);

    this.setState({people});
 }

  setForDelete(person) {
    const checked = !person.checked;
    const people = this.state.people.map((p)=>{
      if(p.id === person.id)
        return {name:person.name, checked};
      return p;
    });

    this.setState({people});
  }

  render () {

    return <PeopleList people={this.state.people} deleteRecords={this.deleteRecords.bind(this)} setForDelete={this.setForDelete.bind(this)}/>;
  }
}

render(<App/>, document.getElementById('app'));
import React,{Component}来自'React';
从'react dom'导入{render};
const Person=({Person,setForDelete})=>(
{person.name}
);
类PeopleList扩展了组件{
render(){
返回(
{this.props.people.map((person,i)=>{
返回;
})}
删除所选记录
);
}
}//结束类
类应用程序扩展了React.Component{
建造师(道具){
超级(道具)
this.state={people:[{id:1,name:'Cesar',checked:false},{id:2,name:'Jose',checked:false},{id:3,name:'Marbel',checked:false}]
}
删除记录(){
const people=this.state.people.filter(p=>!p.checked);
这个.setState({people});
}
塞特福德莱特(人){
const checked=!person.checked;
const people=this.state.people.map((p)=>{
如果(p.id==个人id)
返回{name:person.name,选中};
返回p;
});
这个.setState({people});
}
渲染(){
返回;
}
}
render(,document.getElementById('app'));

你能显示显示个人列表的组件代码吗?@Chris刚刚更新。