![](/img/trans.png)
[英]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.