当前位置: 首页 > 知识库问答 >
问题:

useState集合方法不能立即反映更改(Stackoverflow中建议的解决方案不工作)

钱跃
2023-03-14

每当我使用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]);

结果还是一样。

共有2个答案

吕修伟
2023-03-14

不仅您的函数computePriceSummary()useffect钩子中的任何位置都不会被调用,而且即使在依赖项数组中包含了这3个状态,您也不会看到任何重新渲染。

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

您将得到以下警告:

React Hook useEffect缺少依赖项:“computePriceSummary”。包括它或删除依赖项数组。(反应钩/详尽的DEP)

您可以在本演示中看到它的实际应用。正在更改数据,但在此组件中不会触发重新渲染。

如果将computePriceSummary包含在依赖项数组中(现在总共4个),将触发重新渲染。

但有一个新的警告:

“computePriceSummary”函数使useEffect挂钩(第37行)的依赖项在每次渲染时都发生更改。将其移动到useEffect回调中。或者,将“computePriceSummary”定义包装到它自己的useCallback()钩子中。(反应钩/详尽的DEP)。

让我们修复使用useCallbackhook包装函数的问题。useCallback仅在必要时更改函数本身,并拥有自己的依赖项数组。

const computePriceSummary = useCallback(() => {
    computeSubtotal();
    computeTaxes();
    computeTotal();
  }, []);

同样,您会收到一个依赖项警告,现在它要求将所有其他函数作为依赖项包含:

React Hook useCallback缺少依赖项:“computeSubtotal”、“computeTaxes”和“computeTotal”。包括它们或删除依赖项数组。(反应钩/详尽的DEP)

我们再次使用usecallbackhook和所有其他函数来修复这个问题。将相关状态(每个函数中使用的状态)传递给它们自己的依赖性数组。

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

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

暴夕
2023-03-14

调用setSubtotal时,subtotal变量不会立即更新。这意味着您对computeTaxescomputeTotal的调用是在旧值上运行的。

如果每次更新状态或道具时都会调用您的效果,这将很好,但此定义:

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

表示此效果只调用一次。要解决此问题,请使用以下方法:

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

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

添加第二个效果(使用console.log的效果)不会导致在您的案例中重新运行第一个效果。

 类似资料:
  • 我试图学习钩子,而方法让我感到困惑。我以数组的形式给一个状态赋值初始值。中的set方法不适用于我,无论是否使用扩频运算符。 我在另一台PC上制作了一个API,我正在调用它并获取我想要设置为状态的数据。 这是我的代码: 和都不起作用。 我希望结果变量被推送到movies数组中。

  • 问题内容: 我正在尝试学习钩子,该方法使我感到困惑。我正在将初始值分配给数组形式的状态。即使使用或,in中的set方法对我也不起作用。我已经在另一台PC上创建了一个API,该API正在调用并获取要设置为状态的数据。 这是我的代码: 的以及不工作。可以在这里使用一些帮助。 我希望将结果变量推入movies数组中。 问题答案: 类似于通过扩展或创建的Class组件中的setState,使用钩子提供的更

  • 我正在尝试学习挂钩,方法让我感到困惑。我正在以数组的形式为状态分配初始值。中的set方法不适合我,无论是否使用扩展语法。 我在另一台PC上制作了一个API,我正在调用并获取我想要设置为状态的数据。 这是我的代码: 无论是设置电影(结果)还是设置电影(结果)都不起作用。 我希望将

  • 我写了一个相当基本的js函数,它以编程方式自动将iPhone键盘完美地对准每一个聚焦的输入字段(如果你喜欢,可以随意使用它!)。对齐主要由window.scroll处理——这是一种标准方法,适用于任何浏览器视图,UIWebView除外,因此是phonegap/cordova(2.1)。所以我需要一个变通方法。 我的工作代码: 工作在一切,但UIWebView,这是。正如我上面提到的,除了windo

  • 问题内容: 我正在做一个待办事项应用程序。这是违规代码的非常简化的版本。我有一个复选框: 这是调用复选框的函数: updateItem是映射为分派到redux的函数 我的问题是,当我调用updateItem操作并在console.log状态时,它总是落后1步。如果未选中该复选框且该复选框不为true,则仍将状态为true传递给updateItem函数。我是否需要调用另一个函数来强制状态更新? 问题

  • 我正在尝试让Gradle Artifactory插件来解析工件。 我的build.gradle文件在下面,被替换为正确的主机名 然而,当运行此命令时,它无法解析工件。依赖行是从artiFactory生成的。 我打算使用“旧”发布机制。我的Gradle版本是2.0。 我尝试了一个带有maven2默认值和gradle布局的artifactory存储库。 堆栈跟踪可在以下位置找到:http://text