Javascript 数组语法中的扩展运算符与数组

Javascript 数组语法中的扩展运算符与数组,javascript,arrays,reactjs,typescript,react-hooks,Javascript,Arrays,Reactjs,Typescript,React Hooks,新的反应 我试图在用户单击布尔值“done”时更新它 由于某些原因,此代码不起作用 var updateTodo = todos; updateTodo[Number(id)].done = !updateTodo[Number(id)].done; setTodos(updateTodo); 但这是真的 var updateTodo = [...todos]; updateTodo[Number(id)].done = !updateTodo[Number(id)].done; setTod

新的反应

我试图在用户单击布尔值“done”时更新它

由于某些原因,此代码不起作用

var updateTodo = todos;
updateTodo[Number(id)].done = !updateTodo[Number(id)].done;
setTodos(updateTodo);
但这是真的

var updateTodo = [...todos];
updateTodo[Number(id)].done = !updateTodo[Number(id)].done;
setTodos(updateTodo);
我认为
todos
[…todos]
都返回相同的值,即todos数组,那么为什么第一个代码段不能工作呢

这里是工作
App.tsx
供参考,而不是函数
handleDone
中的工作代码段

import React from "react";

type item = {
  itemId: number;
  todo: string;
  done: boolean;
};

var id = 0;

const App: React.FC = () => {
  const [newTodo, setNewTodo] = React.useState<string>("");
  const [todos, setTodos] = React.useState<item[]>([]);

  const handleChange = (event: any) => {
    const { value } = event.target;
    setNewTodo(value);
  };

  const handleSubmit = (event: any) => {
    setTodos([...todos, { itemId: id, todo: newTodo, done: false }]);
    id++;
    setNewTodo("");
    event.preventDefault();
  };

  const handleDone = (item: any) => {
    // Not Working
    var updateTodo = todos;
    updateTodo[Number(id)].done = !updateTodo[Number(id)].done;
    setTodos(updateTodo);

    // Working Code
    // var updateTodo = [...todos];
    // updateTodo[Number(id)].done = !updateTodo[Number(id)].done;
    // setTodos(updateTodo);
  };

  return (
    <>
      <form>
        <input onChange={handleChange} value={newTodo} type="text" name="todo" placeholder="Enter Todo" />
        <button onClick={handleSubmit}>Add</button>
      </form>
      <ul>
        {todos.map((item, index) => {
          return item.done ? (
            <li id={`${item.itemId}`} onClick={handleDone} style={{ textDecoration: "line-through" }}>
              {item.todo}
            </li>
          ) : (
            <li id={`${item.itemId}`} onClick={handleDone} style={{ textDecoration: "none" }}>
              {item.todo}
            </li>
          );
        })}
      </ul>
    </>
  );
};

export default App;

从“React”导入React;
类型项={
itemId:编号;
todo:字符串;
完成:布尔;
};
var-id=0;
常量应用程序:React.FC=()=>{
常量[newTodo,setNewTodo]=React.useState(“”);
const[todos,setTodos]=React.useState([]);
const handleChange=(事件:any)=>{
const{value}=event.target;
setNewTodo(值);
};
const handleSubmit=(事件:any)=>{
setTodos([…todos,{itemId:id,todo:newTodo,done:false}]);
id++;
setNewTodo(“”);
event.preventDefault();
};
const handleDone=(项目:任意)=>{
//不起作用
var updateTodo=todos;
updateTodo[Number(id)].done=!updateTodo[Number(id)].done;
setTodos(updateTodo);
//工作代码
//var updateTodo=[…todos];
//updateTodo[Number(id)].done=!updateTodo[Number(id)].done;
//setTodos(updateTodo);
};
返回(
添加
    {todos.map((项目,索引)=>{ 退货。完成了吗(
  • {item.todo}
  • ) : (
  • {item.todo}
  • ); })}
); }; 导出默认应用程序;
foo=arr
,然后
foo
计算为与
arr
相同的数组对象
foo=[…arr]
,则foo是通过浅拷贝创建的新数组,更改
foo
(例如添加或删除元素)不会影响
arr
。在这方面,返回或传递值与赋值具有相同的行为(即,不会隐式创建副本/克隆)。有时两者都可以。有时需要使用相同的对象。有时需要一份副本才能正常工作。这实际上取决于以后修改数组的内容以及期望值。最有可能是重复的。重申一下,这两种都是状态突变,两者都不好。但是第二种情况会导致重新渲染,因为
updateTodo
是一个不同的数组,而在第一种情况下,您将状态设置为自身。