我试图通过点击li来切换单个待办事项。
我最初通过在Todo类组件上建立一个状态并从那里修改它来做到这一点,从那时起我将状态移动到TodoApp组件。
我可以通过指定1的索引号来切换单个待办事项,它将切换todo与索引1,但是我似乎无法弄清楚如何获取被点击的li元素的索引。我的li元素嵌套在Todo组件中。
如果我将索引保留为(i)inClick = {()=> this.props.toggleTodo(i)} ,我收到错误,
./ SRC / index.js 第12行:'i'未定义为no-undef
如何正确地将我的List组件中的索引传递给正在Todo组件中执行的 this.props.toggleTodo()函数?
任何帮助将不胜感激!
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import registerServiceWorker from './registerServiceWorker';
// initializing todo
class Todo extends React.Component {
render() {
return (
<ul>
<li className="todo"
onClick={() => this.props.toggleTodo(i)}>
<span className="btn-completed" style={{color: this.props.completed ? '#99cc99' : '#fafafa'}}>{'\u{2714}'}</span>
<span style={{textDecoration: this.props.completed ? 'line-through' : 'none'}}>{this.props.text}</span>
<span className="btn-delete" onClick={() => this.props.onClick(this.props.id)} >{'\u{2716}'}</span>
</li>
</ul>
)
}
}
// initializing list of todos
const List = (props) => (
<div>
{props.todos.map((todo, i) => <Todo key={todo.id} onClick={props.onClick} toggleTodo={props.toggleTodo} {...todo}/>)}
</div>
)
// initializing form
const Form = (props) => (
<form onSubmit={props.onSubmit}>
<input type="text" autoFocus required placeholder="Enter Todo..."
value={props.value}
onChange={props.onChange}
/>
</form>
)
// initializing main app
class TodoApp extends React.Component {
constructor(props) {
super(props);
this.state = {
inputText: '',
todos: []
}
this.onChange = this.onChange.bind(this);
this.addTodo = this.addTodo.bind(this);
this.filterTodo = this.filterTodo.bind(this);
this.toggleAll = this.toggleAll.bind(this);
this.toggleTodo = this.toggleTodo.bind(this);
}
//getting text input value
onChange = (e) => {
this.setState({inputText: e.target.value})
}
// adding todo
addTodo = (e) => {
e.preventDefault();
const newTodos = this.state.todos.concat([{text: this.state.inputText, id: Date.now(), completed: false}])
this.setState({inputText: '', todos: newTodos},
() => console.log(this.state.todos)
)
}
// filtering todo
filterTodo = (id) => {
const filteredTodos = this.state.todos.filter((item) => item.id !== id);
this.setState({todos: filteredTodos});
}
toggleAll = () => {
const newTodos = this.state.todos;
newTodos.forEach(todo =>
todo.completed = !todo.completed
)
this.setState({todos: newTodos}, () => console.log(this.state.todos))
}
toggleTodo(i) {
const newTodos = this.state.todos;
newTodos[i].completed = !newTodos[i].completed
this.setState({todos: newTodos});
}
// rendering view
render() {
return (
<div>
<Form
value={this.state.inputText}
onChange={this.onChange}
onSubmit={this.addTodo}
/>
<button onClick={() => this.toggleTodo(1)}>Toggle All</button>
<List
toggle={this.toggleTodo}
todos={this.state.todos}
onClick={this.filterTodo}
/>
</div>
);
}
}
ReactDOM.render(<TodoApp />, document.getElementById('root'));
registerServiceWorker();
答案 0 :(得分:2)
这应该适合你:
const List = (props) => (
<div>
{props.todos.map((todo, i) => <Todo key={todo.id} onClick={props.onClick} toggleTodo={() => props.toggle(i)} {...todo}/>)}
</div>
)
一旦你这样做,你不需要使用Todo中的i,因为传入的函数已经特定于数组中的特定元素。
onClick={() => this.props.toggleTodo()}>
但是,我认为如果你使用了toggleTodo方法会更好,这样当你做这样的事情时它会起作用,但这需要某种查找:
onClick={() => this.props.toggleTodo(this.props.id)}
编辑:由于onClick
事件位于li
,因此删除工作已停止。一个简单的解决方法是:
<li className="todo">
<span onClick={() => this.props.toggleTodo(i)}>
<span className="btn-completed" style={{color: this.props.completed ? '#99cc99' : '#fafafa'}}>{'\u{2714}'}</span>
<span style={{textDecoration: this.props.completed ? 'line-through' : 'none'}}>{this.props.text}</span>
</span>
<span className="btn-delete" onClick={() => this.props.onClick(this.props.id)} >{'\u{2716}'}</span>
</li>