Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/24.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 使用useState()的concat方法_Javascript_Reactjs - Fatal编程技术网

Javascript 使用useState()的concat方法

Javascript 使用useState()的concat方法,javascript,reactjs,Javascript,Reactjs,我正在学习React钩子,并试图了解useState如何与数组一起工作。因此,我有以下代码: const App = () => { const initialTodos = [ { id: 'a', task: 'Learn React', complete: true, }, { id: 'b', task: 'Learn Firebase', complete: true, }, { id

我正在学习React钩子,并试图了解useState如何与数组一起工作。因此,我有以下代码:

    const App = () => {
      const initialTodos = [
  {
    id: 'a',
    task: 'Learn React',
    complete: true,
  },
  {
    id: 'b',
    task: 'Learn Firebase',
    complete: true,
  },
  {
    id: 'c',
    task: 'Learn GraphQL',
    complete: false,
  },
];
      const [todos, setTodos] = useState(initialTodos);
      const [task, setTask] = useState('');
      const handleChangeInput = event => {
        setTask(event.target.value);
      };
      const handleSubmit = event => {
        if (task) {
          setTodos(todos.concat({ id: 'd', task, complete: false }));
        }
        setTask('');
        event.preventDefault();
      };
      ...
    };
我想问的问题是,为什么我们要使用concat将新对象不可变地添加到数组中?如果mutate和push()怎么办

不要忘记
todos
是一个数组

如果变异并使用push()会怎么样

如react中所述:

永远不要直接改变this.state,因为之后调用setState()可能会 替换你所做的变异。把这个国家当作 不变的

原因:

1/setState分批工作,这意味着不能期望setState立即执行状态更新,因为它是一个异步操作,因此状态更改可能会在稍后的时间点发生,这意味着手动更改状态可能会被setState覆盖

2/业绩。当使用pure component或shouldComponentUpdate时,它们将使用===运算符进行浅层比较,但如果更改状态,对象引用仍将保持不变,因此比较将失败


来源:这是一种极好的媒介。

使用
concat()
方法合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组。-@抱歉,我们需要更改现有数组,为什么需要返回新数组?您也可以使用扩展语法而不是concat
setTodos([…todos,{id:'d',task,complete:false}])
为什么需要返回新数组?
因为react假设状态是不可变的。如果您对数组进行了变异,react无法判断它是否已更改。这是否回答了您的问题@O.O,抱歉,为什么我们需要返回新阵列?如果我们用push()更改现有数组会怎么样?它不会触发重新渲染。不允许您直接改变状态,
[…todos]
是不需要的,因为concat不会改变。您可以执行
[…todos,newTodo]
todos.concat(newTodo)
setTodos(prevTodos => prevTodos.concat({ id: 'd', task, complete: false }));