Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 更改现有对象的状态_Javascript_Reactjs_State - Fatal编程技术网

Javascript 更改现有对象的状态

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

您好,我正在使用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 , 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));
}