Reactjs:未知为什么函数 re-运行 第二次

Reactjs: Unknown why function re-run second time

我开始学习 React,昨天我 运行 遇到了这个问题,请有人解释一下。 当我第一次单击“添加到愿望清单”按钮时,下面的代码 运行 设置了产品 属性“inWishList”:true,但不知道为什么它重新 运行 并将其设置回“假”值。

 const AddToWishList = (id) => {
    setProducts((prev) => {
      const latest_Products = [...prev];
      const selected_Prod_Id = latest_Products.findIndex((x) => x.id === id);
      latest_Products[selected_Prod_Id].inWishList =
        !latest_Products[selected_Prod_Id].inWishList;

      console.log(latest_Products);
      return latest_Products;
    });
  };

_ 下面这段代码工作完美,运行 只有 1 次,但是,我不明白 2 个代码之间的区别

  const AddToWishList = (id) => {
    setProducts((currentProdList) => {
      const prodIndex = currentProdList.findIndex((p) => p.id === id);
      const newFavStatus = !currentProdList[prodIndex].inWishList;
      const updatedProducts = [...currentProdList];
      updatedProducts[prodIndex] = {
        ...currentProdList[prodIndex],
        inWishList: newFavStatus,
      };
      console.log(updatedProducts);
      return updatedProducts;
    });
  };

在第一个片段中,您在切换 inWishList 属性 时改变状态对象。

const AddToWishList = (id) => {
  setProducts((prev) => {
    const latest_Products = [...prev];
    const selected_Prod_Id = latest_Products.findIndex((x) => x.id === id);

    latest_Products[selected_Prod_Id].inWishList =
      !latest_Products[selected_Prod_Id].inWishList; // <-- state mutation

    console.log(latest_Products);
    return latest_Products;
  });
};

第二个片段你不仅浅拷贝了之前的状态,你还浅拷贝了你正在更新的inWishList属性的元素。

const AddToWishList = (id) => {
  setProducts((currentProdList) => {
    const prodIndex = currentProdList.findIndex((p) => p.id === id);
    const newFavStatus = !currentProdList[prodIndex].inWishList;

    const updatedProducts = [...currentProdList]; // <-- shallow copy state

    updatedProducts[prodIndex] = {
      ...currentProdList[prodIndex], // <-- shallow copy element
      inWishList: newFavStatus,
    };

    console.log(updatedProducts);
    return updatedProducts;
  });
};

这两个代码片段功能不同的原因可能是将您的应用渲染到 StrictMode 组件中。

StrictMode

具体参照detecting unexpected side effects.

Strict mode can’t automatically detect side effects for you, but it can help you spot them by making them a little more deterministic. This is done by intentionally double-invoking the following functions:

  • Class component constructor, render, and shouldComponentUpdate methods
  • Class component static getDerivedStateFromProps method
  • Function component bodies
  • State updater functions (the first argument to setState)
  • Functions passed to useState, useMemo, or useReducer

当您将函数传递给 setProducts 时,React 实际上会调用它两次。这在第一个示例中暴露了突变,而第二个示例基本上从未突变状态运行了两次相同的更新,所以结果就是您所期望的。