useState的set方法不会立即反映更改(Stackoverflow中提供的解决方案无效)

3
每当我使用useState设置一个变量时,其值不会立即反映出来。这里有一个useEffect调用computePriceSummary();
useEffect(() => {
    computePriceSummary();
}, []);

computePriceSummary 调用三个函数,如下所示:

const computePriceSummary = () => {
   computeSubtotal();
   computeTaxes();
   computeTotal();
};

这些函数使用useState来设置变量:

const computeTaxes = () => {
   let taxes = 0.05 * subtotal;
   setTaxes(taxes);
};

const computeTotal = () => {
   setTotal(taxes + subtotal);
 };

const computeSubtotal = () => {
   let subtotal = cart.products.reduce((acc, item) => {
     return (acc += item.product.price * item.quantity);
   }, 0);
   setSubtotal(subtotal);
 };

浏览器中显示的值为:
Subtotal: $1200
Taxes: $0
Total: $0

Stackoverflow中的解决方案建议使用useEffect来跟踪变量,因此我这样做了:
useEffect(() => {
   console.log("Use effect to immediately set variables");
 }, [subtotal, taxes, total]);

结果仍然是一样的。

你能在 CodeSandbox 上重现这个问题吗? - hgb123
2个回答

4
当您调用setSubtotal时,subtotal变量不会立即更新。这意味着对computeTaxescomputeTotal的调用将在旧值上进行操作。
如果您的effect在状态或props的每次更新时被调用,则可以正常运行,但是此定义:
useEffect(() => {
    computePriceSummary();
}, []);

这意味着该效果仅被调用一次。为了解决这个问题,可以使用以下方法:

useEffect(() => {
    computePriceSummary();
}, [subtotal, taxes, total]);

每当您的状态变量发生更改时,组件将重新呈现,并通过在效果的依赖项中拥有它们,该效果将被正确地重新触发。

在您的情况下,添加第二个效果(使用console.log的效果)不会导致第一个效果重新运行。


1

不仅你的computePriceSummary()函数在useEffect钩子中没有被调用,即使你将这三个状态包含在依赖数组中,也不会看到任何重新渲染。

useEffect(() => {
    computePriceSummary();
  }, [taxes, total, subtotal]);

您会收到以下警告:
React Hook useEffect缺少依赖项:'computePriceSummary'。要么包含它,要么删除依赖项数组。(react-hooks/exhaustive-deps)
您可以在此演示中看到它的作用。数据正在更改,但在此组件中不会触发重新渲染。
如果在依赖项数组中包含了'computePriceSummary'(总共有4个),那么重新渲染将会被触发。
但是会出现新的警告:
'computePriceSummary'函数使得useEffect Hook(第37行)的依赖项在每次渲染时都发生变化。将其移动到useEffect回调函数内部。或者,将'computePriceSummary'定义封装到自己的useCallback() Hook中。(react-hooks/exhaustive-deps)。
让我们使用useCallback钩子来修复它。useCallback使函数本身仅在必要时才更改,具有自己的依赖项数组。
const computePriceSummary = useCallback(() => {
    computeSubtotal();
    computeTaxes();
    computeTotal();
  }, []);

再次出现依赖项警告,现在要求包含所有其他函数作为依赖项:

React Hook useCallback缺少依赖项:'computeSubtotal'、'computeTaxes'和'computeTotal'。请将它们包含进去或删除依赖项数组。(react-hooks/exhaustive-deps)

我们使用useCallback钩子与所有其他函数再次修复此问题。将相关状态(在每个函数内部使用的状态)传递给它们自己的依赖项数组。

这变得重复了,不是吗?您可能希望在后端执行这些任务,并在React中使用减少的数据。

在这里 您可以看到一个完整的演示,其中模拟购物车在按下按钮时更新。状态已正确设置,没有依赖项警告,功能正常运行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接