我正在尝试使用React创建一个待办事项列表。我可以在显示区域显示列表,也可以删除项目。但是,当我单击一个复选框时,将选中所有复选框,并将该类应用于所有列表项。我不确定我做错了什么。
我尝试使用与删除项目(使用过滤器)相同的逻辑,但它不起作用。我在这里查看其他案例,但他们主要是关于如何使用jQuery。
Here是我问题的工作示例。
这是List类
class List extends Component {
state={
check: false,
strike: 'none'
}
onCheck(item){
this.setState({check: !this.state.check})
if (this.state.strike === 'none'){
this.setState({strike: 'line-through'})
} else {
this.setState({strike: 'none'})
}
}
render() {
const strike = {
textDecoration: this.state.strike,
}
return (
<ul className='list-style'>
{ this.props.items.map((item, index) =>
<li key={index}>
<div className="outer-div">
<div className="item-checkbox">
<input type="checkbox" checked={this.state.check}
onChange={() => this.onCheck(item)} />
</div>
<div className="item-text">
<span style= {strike}> {item} </span>
</div>
<div className="item-remove-div">
<button className="item-remove" onClick={() => this.props.onDeleteList(index)}>
Remove
</button>
</div>
</div>
<br />
</li>
)}
</ul>
)}
}
export default List;
这是主类:
class Main extends Component {
state = {
items: [],
term : "",
}
onChange(event){
this.setState({ term: event });
}
onDelete= (item) =>{
// this.setState ({
// items: this.state.items.filter((i) => i.index !== item.index)
// })
this.state.items.splice(item, 1);
this.setState({items: this.state.items});
}
onSubmit= (event) => {
event.preventDefault();
if (this.state.term.length > 0){
this.setState({
term: '',
items: [...this.state.items, this.state.term]
});
}
}
render() {
return (
<div className="center">
<h1 className="header" > TODO-LIST </h1>
<div className='mainCenter'>
<form className="App" onSubmit={this.onSubmit}>
<input placeholder="add task" value={this.state.term} onChange={(e) => this.onChange(e.target.value)}
className="inputField"/>
<button>Add to the List</button>
</form>
<List items={this.state.items} onDeleteList={this.onDelete}/>
<div className="footer-outer">
<span className="footer"> Number of completed items in an array: {this.state.items.length} </span>
</div>
</div>
</div>
);
}
}
答案 0 :(得分:2)
我修改了你的SlackBlitz。现在,您可以正确添加新待办事项,检查个人任务(在todo点击时切换检查)并在页脚中查看正确的checked
计数器。
查看todo-list-react演示。
import React, { Component } from 'react';
import TodoList from './List';
import './style.css';
class Main extends Component {
constructor() {
super();
this.state = {
items: [],
term: ''
};
}
handleChange = event => {
this.setState({ term: event.target.value });
}
handleItemClick = ({ value, checked }) => {
this.setState({
items: this.state.items.map(item => item.value === value ? { value, checked: !checked } : item)
});
}
onSubmit = event => {
event.preventDefault();
if (this.state.term.length > 0) {
this.setState({
term: '',
items: [...this.state.items, { value: this.state.term, checked: false }]
});
}
}
handleDelete = index => {
console.info('todo: remove todo at index', index);
// deletion logic... keep in mind that using index as key properties on jsx could breaks the correct functioning of this component.
}
render() {
return (
<div className="center">
<h1 className="header" > TODO-LIST </h1>
<div className='mainCenter'>
<form className="App" onSubmit={this.onSubmit}>
<input placeholder="add task" value={this.state.term} onChange={this.handleChange}
className="inputField"/>
<button>Add to the List</button>
</form>
<TodoList
onTodoClick={this.handleItemClick}
onDelete={this.handleDelete}
todos={this.state.items}
/>
<div className="footer-outer">
<span className="footer">
Number of completed items in an array:
{this.state.items.filter(item => item.checked).length}
</span>
</div>
</div>
</div>
);
}
}
export default Main
import React, { Component } from 'react';
import './style.css';
class List extends Component {
render() {
const { todos, onTodoClick, onDelete } = this.props;
return (
<ul className='list-style'>
{
todos.map((item, index) =>
<li key={index}>
<div className="outer-div">
<div className="item-checkbox">
<input type="checkbox" checked={item.checked}
onChange={() => onTodoClick(item)} />
</div>
<div className="item-text">
<span style={checkboxStyle(item.checked)}>{item.value}</span>
</div>
<div className="item-remove-div">
<button className="item-remove"
onClick={() => onDelete(index)}>
Remove
</button>
</div>
</div>
<br />
</li>
)}
</ul>
)}
}
function checkboxStyle(checked) {
return {
textDecoration: checked? 'line-through' : 'none',
};
}
export default List;
除了这个答案,我建议你考虑从数组索引的每个jsx-element differen中添加一个唯一的key
属性。当前的实现没有问题,但是一旦你开始删除todo项目可能会显示错误的数据。
阅读React文档中的List and Keys和Medium上的这篇文章,其中介绍了使用indix作为键时可能出现的错误。
答案 1 :(得分:1)
您的所有列表项目被删除的原因&#39;是因为您只为列表中的所有项目保留了一个州。您需要为列表中的每个项目设置checked
或strike
状态。但是,当我查看您的评论时,我意识到您已经知道了。
您在代码中还有其他几个不一致的地方:
onDelete= (item) =>{
this.state.items.splice(item, 1);
this.setState({items: this.state.items});
}
对state
进行直接更改可能会导致意外错误和异常行为。更好的方法是:
onDelete = (item) => {
const items = this.state.items.slice();
items.splice(item, 1);
this.setState({
items: items,
});
}
有关详细信息,请参阅此文章: https://medium.com/pro-react/a-brief-talk-about-immutability-and-react-s-helpers-70919ab8ae7c