[英]JavaScript Todo List - When I click 'edit' button, it doesn't show input to be able to change a todo
[英]Checkbox doesn't change its value on click in React todo application
请帮我解决这个问题,我不明白我做错了什么。 因此,当我单击复选框时,值不会更改(如果在单击单击时默认为true
,则它应该为false
)。 为此,在todoList
组件的onChange
中,我正在调用handleClick
函数,在那里我更改了todo.completed
值(基本上是切换值)。
在App.js
的handleClick
方法中,当从 map 函数返回值之前执行console.log(todo)
切换正常,但它没有在updatedTodo
更新。
应用程序.js
import TodosData from "./todoData";
import TodoList from "./todoList";
import "./styles.css";
class App extends Component {
constructor() {
super();
this.state = {
todos: TodosData
}
this.handleChange = this.handleChange.bind(this)
}
handleChange(id) {
this.setState(prevState => {
const updatedTodo = prevState.todos.map(todo => {
// console.log(updatedTodo);
if(todo.id === id) {
console.log("before the opt "+todo.completed);
todo.completed = !todo.completed
console.log("after the opt "+todo.completed);
}
//console.log(todo);
return todo;
})
console.log(updatedTodo);
return {
todos: updatedTodo
}
});
}
render() {
const todoDataComponents = this.state.todos.map(item => {
return <TodoList key = {item.id} item = {item} handleChange = {this.handleChange} />
})
return (
<div className="todo-list">{todoDataComponents}</div>
);
}
}
export default App;
待办事项列表.jsx
class TodoList extends Component {
constructor(props) {
super(props);
this.state = {}
}
render() {
// console.log(this.props)
return (
<div className="todo-item">
<input
type="checkbox"
checked={this.props.item.completed}
onChange = {() => this.props.handleChange(this.props.item.id)}
/>
<p>{this.props.item.text}</p>
</div>
);
}
}
export default TodoList;
todoData.js
const TodosData = [
{ id: 1, text: "Coding", completed: true },
{ id: 2, text: "Exercise", completed: false },
{ id: 3, text: "Learning", completed: true },
{ id: 4, text: "Programming", completed: true },
{ id: 5, text: "inspire", completed: false },
{ id: 6, text: "motivation", completed: true }
];
export default TodosData;
我在您的handleChange()
方法handleChange()
不到任何错误,它应该可以正常工作。 但是,我刚刚更新了您的一些代码,您可以在下面进行测试。
我更改了您的TodoList
的名称,因为它实际上不是一个列表而是一个项目。 我还把它改成了一个功能组件,因为它只是展示性的,不需要有自己的状态。 与其在input
之后添加p
标签,不如使用label
使其可访问。
我并没有真正更改您的handleChange()
方法中的任何内容,只是删除了console.log
并且它按预期工作。
更新:您正在使用React.StrictMode
,其中 React 在开发中渲染所有内容两次。 当您的handleChange()
运行两次时,它会两次设置被点击的待办事项的completed
状态,使其设置回其原始状态。 所以,如果这是false
的第一渲染其设置为true
的点击,但它再次呈现和第二个它的回false
。 你不会注意到它,因为它非常快。
为了避免它,你需要避免改变任何东西。 所以我更新了你的onChange
处理程序,如果已completed
属性发生更改,它会返回一个新对象。
随意运行下面的代码片段并单击复选框或项目文本。
const TodosData = [ { id: 1, text: 'Coding', completed: true }, { id: 2, text: 'Exercise', completed: false }, { id: 3, text: 'Learning', completed: true }, { id: 4, text: 'Programming', completed: true }, { id: 5, text: 'Inspire', completed: false }, { id: 6, text: 'Motivation', completed: true }, ]; function TodoItem(props) { const { handleChange, item } = props; return ( <div className="todo-item"> <input type="checkbox" id={`item-${item.id}`} checked={item.completed} onChange={() => handleChange(item.id)} /> <label htmlFor={`item-${item.id}`}>{item.text}</label> </div> ); } class App extends React.Component { constructor() { super(); this.state = { todos: TodosData, }; this.handleChange = this.handleChange.bind(this); } handleChange(id) { this.setState((prevState) => { const updatedTodo = prevState.todos.map((todo) => { return todo.id === id ? { ...todo, completed: !todo.completed, } : todo; }); return { todos: updatedTodo, }; }); } render() { const { todos } = this.state; return ( <div className="todo-list"> {todos.map((item) => ( <TodoItem key={item.id} item={item} handleChange={this.handleChange} /> ))} </div> ); } } ReactDOM.render( <React.StrictMode> <App /> </React.StrictMode>, document.getElementById('root') );
body { font-family: sans-serif; line-height: 1.6; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script> <div id="root"></div>
您可以在一行中完成,而不是使用额外的变量。 你能看看这是否适合你。
handleChange(id) {
this.setState(prevState => prevState.map(todo => todo.id === id ? {...todo, completed: !todo.completed} : todo )
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.