列表项没有正确删除(反应)
Posted
技术标签:
【中文标题】列表项没有正确删除(反应)【英文标题】:list items are not deleting properly (React) 【发布时间】:2018-09-09 22:01:36 【问题描述】:感谢您对我的笔记应用程序的帮助。假设我的笔记列表上有 3 个笔记。我想删除列表顶部的注释。无论我尝试删除哪一个,总是首先删除列表最底部的任何一个音符。我检查了 React 控制台,应用组件状态中的 notes 数组显示它已正确删除。但在实际视图本身中,它不是。如何获取它以便删除我选择的确切注释?
class App extends Component
constructor(props)
super(props);
this.state =
notes: [],
title: "",
details: ""
this.updateTitle = this.updateTitle.bind(this);
this.updateDetails = this.updateDetails.bind(this);
this.submitHandler = this.submitHandler.bind(this);
this.deleteHandler = this.deleteHandler.bind(this);
updateTitle(event)
this.setState( title: event.target.value );
updateDetails(event)
this.setState( details: event.target.value );
submitHandler(e)
e.preventDefault();
if (!this.state.title.length || !this.state.details.length)
return;
const newNote =
newTitle: this.state.title,
newDetails: this.state.details
this.setState(prevState => (
notes: prevState.notes.concat(newNote),
title: "",
details: ""
))
deleteHandler(id)
this.setState(prevState => (
notes: prevState.notes.filter((el)=> el !== id)
))
render()
return (
<div className="container">
<h1 className="title">React Notes App</h1>
<NoteForm
titleValue=this.state.title
detailsValue=this.state.details
titleHandle=this.updateTitle
detailsHandle=this.updateDetails
onSubmit=this.submitHandler
/>
<div className="entry-section">
this.state.notes.map((note,i) => (
<NoteEntry
key=i
title=note.newTitle
details=note.newDetails
deleteNote=this.deleteHandler.bind(this,note)
/>
))
</div>
</div>
);
const NoteForm = (props) =>
return (
<div>
<form className="form-section">
<input
className="title-input"
type="type"
placeholder="Title"
value=props.titleValue
onChange=props.titleHandle
/>
<br />
<textarea
className="details-input"
cols="20"
rows="3"
placeholder="Details"
value=props.detailsValue
onChange=props.detailsHandle
/>
<br />
<button
className="input-button"
onClick=props.onSubmit
>Add Note</button>
</form>
</div>
)
class NoteEntry extends Component
constructor(props)
super(props);
this.state =
display: false,
editing: false,
editTitle: this.props.title,
editDetails: this.props.details
this.displayToggle = this.displayToggle.bind(this);
this.edit = this.edit.bind(this);
this.save = this.save.bind(this);
displayToggle()
this.setState(prevState => (
display: !prevState.display
))
edit()
this.setState(
editing: true
)
save()
let titleVal = this.refs.updateTitle.value;
let detailsVal = this.refs.updateDetails.value;
this.setState(
editTitle: titleVal,
editDetails: detailsVal,
editing: false
)
render()
return (
<div className="entry">
<div className="entry-header" onClick=this.state.editing ? null : this.displayToggle>
this.state.editing ? (
<input ref="updateTitle" className="edit-title" type="text" defaultValue=this.state.editTitle />
) : (
<h2 className="entry-title">this.state.editTitle</h2>
)
<p className="timestamp">this.displayTime</p>
</div>
<hr />
<div className="entry-content " + (!this.state.display ? "hide-details" : null)>
this.state.editing ? (
<textarea ref="updateDetails" className="edit-details" cols="10" rows="2" defaultValue=this.state.editDetails></textarea>
) : (
<p className="details">this.state.editDetails</p>
)
<div className="entry-buttons">
this.state.editing ? (
<button className="save" onClick=this.save>Save</button>
) : (
<button className="edit" onClick=this.edit>Edit</button>
)
<button className="delete" onClick=this.props.deleteNote>Delete</button>
</div>
</div>
</div>
)
【问题讨论】:
【参考方案1】:使用index
作为您的key
会发生此错误。 React 使用key
属性来跟踪列表中的元素。当您从数组的中间删除一个元素时,索引不会自行删除,而是会重新排列,最后一个索引会消失。这就是为什么数组中的最后一个元素总是被删除的原因。
对于这个解决方案,我提供了注释的title
作为key
,但这可能并不总是唯一的。使用生成的键或字段组合作为键会更好
class NoteEntry extends React.Component
constructor(props)
super(props);
this.state =
display: false,
editing: false,
editTitle: this.props.title,
editDetails: this.props.details
this.displayToggle = this.displayToggle.bind(this);
this.edit = this.edit.bind(this);
this.save = this.save.bind(this);
displayToggle()
this.setState(prevState => (
display: !prevState.display
))
edit()
this.setState(
editing: true
)
save()
let titleVal = this.refs.updateTitle.value;
let detailsVal = this.refs.updateDetails.value;
this.setState(
editTitle: titleVal,
editDetails: detailsVal,
editing: false
)
render()
return (
<div className="entry">
<div className="entry-header" onClick=this.state.editing ? null : this.displayToggle>
this.state.editing ? (
<input ref="updateTitle" className="edit-title" type="text" defaultValue=this.state.editTitle />
) : (
<h2 className="entry-title">this.state.editTitle</h2>
)
<p className="timestamp">this.displayTime</p>
</div>
<hr />
<div className="entry-content " + (!this.state.display ? "hide-details" : null)>
this.state.editing ? (
<textarea ref="updateDetails" className="edit-details" cols="10" rows="2" defaultValue=this.state.editDetails></textarea>
) : (
<p className="details">this.state.editDetails</p>
)
<div className="entry-buttons">
this.state.editing ? (
<button className="save" onClick=this.save>Save</button>
) : (
<button className="edit" onClick=this.edit>Edit</button>
)
<button className="delete" onClick=this.props.deleteNote>Delete</button>
</div>
</div>
</div>
)
const NoteForm = (props) =>
return (
<div>
<form className="form-section">
<input
className="title-input"
type="type"
placeholder="Title"
value=props.titleValue
onChange=props.titleHandle
/>
<br />
<textarea
className="details-input"
cols="20"
rows="3"
placeholder="Details"
value=props.detailsValue
onChange=props.detailsHandle
/>
<br />
<button
className="input-button"
onClick=props.onSubmit>
Add Note
</button>
</form>
</div>
)
class App extends React.Component
constructor(props)
super(props);
this.state =
notes: [],
title: "",
details: ""
this.updateTitle = this.updateTitle.bind(this);
this.updateDetails = this.updateDetails.bind(this);
this.submitHandler = this.submitHandler.bind(this);
this.deleteHandler = this.deleteHandler.bind(this);
updateTitle(event)
this.setState( title: event.target.value );
updateDetails(event)
this.setState( details: event.target.value );
submitHandler(e)
e.preventDefault();
if (!this.state.title.length || !this.state.details.length)
return;
const newNote =
newTitle: this.state.title,
newDetails: this.state.details
this.setState(prevState => (
notes: prevState.notes.concat(newNote),
title: "",
details: ""
))
deleteHandler(id)
this.setState(prevState => (
notes: prevState.notes.filter((el)=> el !== id)
))
render()
return (
<div className="container">
<h1 className="title">React Notes App</h1>
<NoteForm
titleValue=this.state.title
detailsValue=this.state.details
titleHandle=this.updateTitle
detailsHandle=this.updateDetails
onSubmit=this.submitHandler
/>
<div className="entry-section">
this.state.notes.map((note,i) => (
<NoteEntry
key=note.newTitle
title=note.newTitle
details=note.newDetails
deleteNote=this.deleteHandler.bind(this,note)
/>
))
</div>
</div>
);
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
【讨论】:
以上是关于列表项没有正确删除(反应)的主要内容,如果未能解决你的问题,请参考以下文章