TodoApp - 使用索引切换待办事项时遇到问题
TodoApp - trouble with toggle todo using index
我正在尝试通过单击 li 来切换单个待办事项。
我最初是通过在 Todo class 组件上建立一个状态并从那里修改它来做到这一点的,从那时起我将状态移动到 TodoApp 组件。
我可以通过用 1 指定索引号来切换单个待办事项,它会用索引 1 来切换待办事项,但是我似乎无法弄清楚如何获取单击的 li 元素的索引。我的 li 元素嵌套在 Todo 组件中。
如果我在 onClick={() => this.props.toggleTodo(i)} 中将索引保留为 (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();
这应该适合你:
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>
我正在尝试通过单击 li 来切换单个待办事项。
我最初是通过在 Todo class 组件上建立一个状态并从那里修改它来做到这一点的,从那时起我将状态移动到 TodoApp 组件。
我可以通过用 1 指定索引号来切换单个待办事项,它会用索引 1 来切换待办事项,但是我似乎无法弄清楚如何获取单击的 li 元素的索引。我的 li 元素嵌套在 Todo 组件中。
如果我在 onClick={() => this.props.toggleTodo(i)} 中将索引保留为 (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();
这应该适合你:
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>