在调用状态设置器之前修改状态

时间:2021-02-09 14:06:12

标签: reactjs react-hooks antd

我有一个带有单个输入的表单,它接受一些值,向后端发送请求以创建一个新实体,并通过将新值添加到项目集合来更新前端。

在表单提交时执行的处理程序:

const handleItemInsert = async (item: any): Promise<void> => {
    console.log('BEFORE ITEM CREATE', items);

    const newItem: IItem = await service.addNewItemAsync(item);

    console.log('AFTER ITEM ADD', items);
    console.log(newItem);

    setItems((items) => [...items, newItem]);
}

我的问题是,第一次我添加一个新项目的状态以某种方式被修改(newItem 被添加到 items 集合),甚至在服务获得之前叫。此外,新项目被添加了两次,我不知道为什么。我检查过的每个相关函数都会被调用一次,无论是否使用 StrictMode,我都遇到了这个问题,所以问题不应该基于此。

Here is a full Codesandbox sample 的问题。

我已将日志放入反映流程中问题的函数调用中(您可以在代码和框控制台窗口中查看它们)。我可能会遗漏一些非常微不足道的东西,但此时我真的不知道错误在哪里。

另外,如果问题出在通过 antdonFinish 方法提交自己的表单的处理上(因为我正在传递一个异步方法),它仍然应该执行更新逻辑在日志之后,不要添加项目两次。

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

由于您的服务正在改变 ITEMS 并且您将该值设置为状态,因此您无意中修改了 React 的状态。

更新效果以在设置项目时创建项目的浅表副本:

  useEffect(() => {
    async function fetchItems() {
      console.log("FETCH ITEMS CALLED.");

      const items = await service.getAllItemsAsync();

      console.log("INITIAL ITEMS", items);

      setItems([...items]);
    }

    fetchItems();
  }, []);

Edit compassionate-dhawan-o8h73

相关问题