所以,我有一个带复选框的项目列表,就像经典的待办事项应用程序一样。
当我选择" Johnny"然后单击,"删除所选记录,"约翰尼确实离开了。耶!
但是,一旦Johnny离开,现在就会检查Renee。
我没有点击Renee。我只点击了Johnny,但是一旦Johnny被删除,Renee就被检查了。跆拳道?
显然,正在发生的事情是复选框DOM保持被检查的状态,即使我刚刚清除了复选框。
我尝试通过更新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;
Person组件中的其他所有内容都正常工作。删除任何记录后,如何取消选中所有复选框?
更新:这是人员列表,包含所有人员的组件。
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;
答案 0 :(得分:6)
不要将数组索引用作关键属性!
密钥是React用于识别DOM元素的唯一支柱。如果密钥与以前相同,在您的情况下0
React假定DOM元素表示与以前相同的内容 - 即使现在还有另一个文本。
因此,React会不重新呈现状态并更新已检查的属性。
使用独特的内容,例如:
<Person key={person + '_' + i} ...
答案 1 :(得分:3)
尝试更改PeopleList
{this.props.people.map((person, i) => {
return <Person key={person._id} person={person} setForDelete={this.props.setForDelete} />;
})}
答案 2 :(得分:3)
我认为你可能会遇到状态问题并传递功能。我创建了一个示例,它使用简单的map和filter函数来镜像当前实现,以模仿删除。如果我不得不猜测您可能无法跟踪检查和删除哪些数据,并且可能会缓存已检查的值。正如您在下面的代码中所看到的,这里有一些建议,您可以实现以使代码更容易:
context
或者一个帮助你跟踪状态的库,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'));