我在Reactjs中创建了一个项目,其中有一个要显示在自定义列表中的名称列表。每个项目都有一个删除项目的按钮,但是,无论我单击哪个按钮,无论我单击哪个列表项目,最后一个项目都会从列表中删除。
我已经尝试使用js控制台调试我的代码,但是由于控制台显示正确的状态,而组件“列表”呈现状态对象中不再存在的列表项,这使问题变得更加奇怪。 / p>
import React, { Component } from 'react';
import './ListItem'
import ListItem from './ListItem';
class List extends Component {
constructor(props) {
super(props);
this.state = {
items: [
{name: 'Tobi'},
{name: 'Maxi'},
{name: 'David'},
{name: 'Peter'},
]
}
}
removeItem = (id) => {
let few = this.state.items;
few.splice(id,1);
//console.log(this.state.items);
this.setState({items: few}, function(){
console.log(this.state.items.map((item) => item.name));
this.forceUpdate();
});
}
render() {
return (
<div>
<ul>
{this.state.items.map((item, i) => <ListItem name={item.name} key={i} id={i} remove={this.removeItem}/>)}
</ul>
</div>
);
}
}
import React, { Component } from 'react';
class ListItem extends Component {
constructor(props) {
super(props);
this.state = {
name: this.props.name,
id: this.props.id
}
}
test = () => {
this.props.remove(this.state.id);
}
render() {
return (
<li>{this.state.name} <button onClick={() => this.test()}>click me</button></li>
);
}
}
export default ListItem;
据说我希望删除正确的列表项,但是即使状态对象说的不同,它仍然是最后一个不再渲染的项目。
答案 0 :(得分:1)
主要问题是您将数组索引用作key
。当您第一次呈现ListItems时:
假设您删除了索引为1的项目,所有其他项目都会转移索引:
React将仅比较键,并且由于第一和第二渲染之间的唯一区别是不存在key = {3}的项目,因此该项目将从dom中删除。
还要避免直接改变状态(few.splice(id,1)
),并尝试避免this.forceUpdate()
尝试在数据中使用实际ID:
import React, { Component } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
class List extends Component {
constructor(props) {
super(props);
this.state = {
items: [
{ id: 1, name: "Tobi" },
{ id: 2, name: "Maxi" },
{ id: 3, name: "David" },
{ id: 4, name: "Peter" }
]
};
}
removeItem = id => {
let few = this.state.items.filter(item => item.id !==id);
//console.log(this.state.items);
this.setState({ items: few }, function() {
console.log(this.state.items.map(item => item.name));
//this.forceUpdate();
});
};
render() {
return (
<div>
<ul>
{this.state.items.map((item, i) => (
<ListItem
name={item.name}
key={item.id}
id={item.id}
remove={this.removeItem}
/>
))}
</ul>
</div>
);
}
}
class ListItem extends Component {
constructor(props) {
super(props);
this.state = {
name: this.props.name,
id: this.props.id
};
}
test = () => {
this.props.remove(this.state.id);
};
render() {
return (
<li>
{this.state.name} <button onClick={() => this.test()}>click me</button>
</li>
);
}
}
function App() {
return (
<div className="App">
<List />
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);