как в React удалить элемент
Пример моего кода, как я удаляю элемент, но корректно удаляется только в последовательности от последнего элемента к первому, как корректно реализовать удаление?
class List extends React.Component{
constructor(props){
super(props);
this.state = {type: props.type, items: props.items}
}
remove(id){
let tmpItems = this.state.items.filter((el) => el.id != id);
this.setState( {
items: tmpItems
})
}
render(){
return <div className="row d-flex flex-row align-items-center justify-content-center w-100 h-100 overflow-auto m-0 h-auto">
{this.state.items.map((item) => <Items item = {item} remove = {this.remove.bind(this)} />)}
</div>
}
}
class Items extends React.Component{
constructor(props){
super(props);
this.setName = this.setName.bind(this);
this.setContent = this.setContent.bind(this);
this.setDate = this.setDate.bind(this);
this.state = {id : this.props.item.id, name: this.props.item.name , content: this.props.item.content, date : this.props.item.date, type : props.item.type , isNew: props.item.isNew}
}
componentDidMount(){
}
setName(e){
let text = e.target.textContent.slice(0, 50);
this.setState({name: text})
setTimeout(() => this.afterSet(), 0)
}
setContent(e){
let text = e.target.textContent.slice(0, 1000);
this.setState({content: text})
setTimeout(() => this.afterSet(), 0)
}
setDate(e){
this.setState({date: e.target.text})
setTimeout(() => this.afterSet(), 0)
}
afterSet(){
$.post('/toDoSave', this.state, (data) => {
if (data.isNew){
this.setState({id: data.id, isNew: false})
}
})
}
render(){
return (
<div className = " item container" key = {this.state.id} >
<div contentEditable={true} placeholder = {"Имя"} className="note-name border-bottom border-1 m-2 d-flex align-items-center outline-none my-text text-break overflow-auto" onBlur = {this.setName}>
{this.state.name}
</div>
<div contentEditable={true} placeholder = {"Текст"} className="note-content border-1 m-2 outline-none my-text overflow-auto text-break my-scroll" onBlur = {this.setContent}>
{this.state.content}
</div>
<div className="note-button-group m-2 border-top border-1 d-flex flex-row align-items-center justify-content-between">
<div class="d-flex flex-row">
<div className="note-button p-2 ms-1"><i class="fa-solid fa-chart-bar"></i></div>
</div>
<div class="d-flex flex-row">
<div className="note-button p-2 ms-1"><i class="fa-solid fa-circle-exclamation"></i></div>
</div>
<div class="d-flex flex-row">
<div className="note-button p-2 ms-1"><i class="fa-solid fa-calendar-days"></i></div>
<div className="note-button p-2 ms-1" onClick = {() => {this.props.remove(this.state.id)}} ><i class="fa-solid fa-trash-can"></i></div>
</div>
</div>
</div>
)
}
}
Ответы (1 шт):
Автор решения: entithat
→ Ссылка
Добавить key={} надо было для каждого элемента списка. Вы не там его добавили изначально.
import React from "react";
class List extends React.Component {
constructor(props) {
super(props);
this.state = {
type: props.type,
items: props.items
};
}
remove(id) {
console.log(id);
this.setState({
items: this.state.items.filter((el) => el.id !== id)
});
}
render() {
return (
<div className="row d-flex flex-row align-items-center justify-content-center w-100 h-100 overflow-auto m-0 h-auto">
{this.state.items.map((item) => (
<Items key={item.id} item={item} remove={this.remove.bind(this)} />
))}
</div>
);
}
}
class Items extends React.Component {
constructor(props) {
super(props);
this.setName = this.setName.bind(this);
this.setContent = this.setContent.bind(this);
this.setDate = this.setDate.bind(this);
this.state = {
id: this.props.item.id,
name: this.props.item.name,
content: this.props.item.content,
date: this.props.item.date,
type: props.item.type,
isNew: props.item.isNew
};
}
setName(e) {
this.setState({ name: e.target.textContent.slice(0, 50) });
setTimeout(() => this.afterSet(), 0);
}
setContent(e) {
this.setState({ content: e.target.textContent.slice(0, 1000) });
setTimeout(() => this.afterSet(), 0);
}
setDate(e) {
this.setState({ date: e.target.text });
setTimeout(() => this.afterSet(), 0);
}
afterSet() {
$.post('/toDoSave', this.state, (data) => {
if (data.isNew) {
this.setState({id: data.id, isNew: false})
}
})ж
}
render() {
return (
<div className="item container">
<div
contentEditable={true}
placeholder={"Имя"}
className="note-name border-bottom border-1 m-2 d-flex align-items-center outline-none my-text text-break overflow-auto"
onBlur={this.setName}
>
{this.state.name}
</div>
<div
contentEditable={true}
placeholder={"Текст"}
className="note-content border-1 m-2 outline-none my-text overflow-auto text-break my-scroll"
onBlur={this.setContent}
>
{this.state.content}
</div>
<div className="note-button-group m-2 border-top border-1 d-flex flex-row align-items-center justify-content-between">
<div className="d-flex flex-row">
<div className="note-button p-2 ms-1">
<i className="fa-solid fa-chart-bar"></i>
</div>
</div>
<div className="d-flex flex-row">
<div className="note-button p-2 ms-1">
<i className="fa-solid fa-circle-exclamation"></i>
</div>
</div>
<div className="d-flex flex-row">
<div className="note-button p-2 ms-1">
<i className="fa-solid fa-calendar-days"></i>
</div>
<div
className="note-button p-2 ms-1"
onClick={() => {
this.props.remove(this.props.item.id);
}}
>
remove
<i className="fa-solid fa-trash-can"></i>
</div>
<hr />
</div>
</div>
</div>
);
}
}
export default function App() {
return (
<List
items={[
{
id: 1,
name: "name1",
content: "namdse1",
date: new Date(),
type: "name1",
isNew: false
},
{
id: 2,
name: "name2",
content: "namdse2",
date: new Date(),
type: "name2",
isNew: false
},
{
id: 3,
name: "name3",
content: "namdse3",
date: new Date(),
type: "name3",
isNew: false
}
]}
/>
);
}
P.S. Используйте функциональные компоненты если можно, будет выглядеть читабельнее.