Javascript 更改现有对象的状态
您好,我正在使用react上下文,我遇到了一个问题 我有一个包含所有逻辑的组件:Javascript 更改现有对象的状态,javascript,reactjs,state,Javascript,Reactjs,State,您好,我正在使用react上下文,我遇到了一个问题 我有一个包含所有逻辑的组件: import React , {useContext} from 'react'; import {TodoContext} from '../../contexts/todo-context'; import Todo from './Todo'; import './Todos.css'; export default function TodoList() { const [todos , set
import React , {useContext} from 'react';
import {TodoContext} from '../../contexts/todo-context';
import Todo from './Todo';
import './Todos.css';
export default function TodoList() {
const [todos , setTodos] = useContext(TodoContext);
const markComplete = (e) => {
setTodos(prevState => [...prevState , {...e.target.value , done:true} ]);
console.log(todos);
}
return (
<div className="TodoContainer">
{todos.map(todo => (<Todo key={todo.id} todo={todo} markComplete={markComplete} /> ))}
</div>
)
}
它还生成一个错误,表示我应该向下传递一个键(我已经在这样做了)
国家:
const [todo, setTodo] = useState([
{
title : 'Do the dishes',
done : false ,
id: 123
},
{
title : 'wash car',
done : false ,
id: 423
},
{
title : 'Buy pen',
done : false ,
id: 323
}
]);
更新状态的方式是错误的 请注意,在待办事项中,您做到了:
而todo
本身就是一个对象,这意味着执行此操作时:
setTodos(prevState => [...prevState , {...e.target.value , done:true} ]);
你基本上是错误地散布了这个物体。事实上,下一次状态更新的结果是:
0: {title: "Do the dishes", done: false, id: 123}
1: {title: "wash car", done: false, id: 423}
2: {title: "Buy pen", done: false, id: 323}
3: {0: "[", 1: "o", 2: "b", 3: "j", 4: "e", 5: "c", 6: "t", 7: " ", 8: "O", 9: "b", 10: "j", 11: "e", 12: "c", 13: "t", 14: "]", done: true}
这解释了您得到的唯一键
错误
一种可能的解决方案是对传递项目id和已检查状态的更改处理程序使用包装:
function Todo({todo , markComplete}) {
const handleChange = React.useCallback(e => {
markComplete(todo.id, e.target.checked);
}, [todo, markComplete]);
return (
<div>
<input type="checkbox" value={todo.id} onChange={handleChange}></input>
<li>{todo.title}</li>
<div className="spacer"></div>
</div>
)
}
我还建议在上述函数中使用useCallback
这是一把小提琴:
0: {title: "Do the dishes", done: false, id: 123}
1: {title: "wash car", done: false, id: 423}
2: {title: "Buy pen", done: false, id: 323}
3: {0: "[", 1: "o", 2: "b", 3: "j", 4: "e", 5: "c", 6: "t", 7: " ", 8: "O", 9: "b", 10: "j", 11: "e", 12: "c", 13: "t", 14: "]", done: true}
function Todo({todo , markComplete}) {
const handleChange = React.useCallback(e => {
markComplete(todo.id, e.target.checked);
}, [todo, markComplete]);
return (
<div>
<input type="checkbox" value={todo.id} onChange={handleChange}></input>
<li>{todo.title}</li>
<div className="spacer"></div>
</div>
)
}
const markComplete = (id, checked) => {
setTodos(prevState => prevState.map(it => it.id === id ? ({ ...it, done: checked }) : it));
}