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
组件中。
具体参照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 实际上会调用它两次。这在第一个示例中暴露了突变,而第二个示例基本上从未突变状态运行了两次相同的更新,所以结果就是您所期望的。
我开始学习 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
组件中。
具体参照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
, andshouldComponentUpdate
methods- Class component static
getDerivedStateFromProps
method- Function component bodies
- State updater functions (the first argument to
setState
)- Functions passed to
useState
,useMemo
, oruseReducer
当您将函数传递给 setProducts
时,React 实际上会调用它两次。这在第一个示例中暴露了突变,而第二个示例基本上从未突变状态运行了两次相同的更新,所以结果就是您所期望的。