简体   繁体   English

为什么我的 React 组件中的值没有更新?

[英]Why isn't the value updating in my React component?

This seems to be a problem unique to react as I am unable to replicate it using plain JavaScript.这似乎是一个独特的反应问题,因为我无法使用纯 JavaScript 复制它。 The issue is that I use a state variable within a function, but the function will use the value that the variable had whenever the function was defined, rather than the current value of the variable:问题是我在函数中使用状态变量,但函数将使用该变量在定义函数时的值,而不是变量的当前值:

import React, { useEffect, useState } from 'react';
export default function Home() {
  const [val, setVal] = useState(0);
  const [f, setF] = useState(null);

  useEffect(function(){
    setF(()=>function(){console.log(val)})
    setVal(2)
  },[])

  console.log("Value is", val)
  return (
    <div 
      onClick={f} 
      style={{
        backgroundColor: 'red',
        height: 100,
        width: 100,
      }}
    >

    </div>
  )
}

After clicking the div, the output will be:单击 div 后,输出将是:

Value is 0
Value is 2
0

Clearly, the variable val is updated to be 2, but when the function f is run it prints out the value that val had when the function was defined rather than its new updated value.显然,变量 val 被更新为 2,但是当函数 f 运行时,它打印出 val 在定义函数时的值,而不是它的新更新值。

I've worked around this by having the function be redefined any time the state values it depends on change, but this is less than ideal, as I would expect the function to always use the new value.我已经通过在它所依赖的状态值发生变化时重新定义函数来解决这个问题,但这不太理想,因为我希望函数始终使用新值。 It seems in regular javascript this does not occur, or at least I cannot figure out how to make it happen.似乎在常规 javascript 中不会发生这种情况,或者至少我不知道如何使它发生。

Why is this happening?为什么会这样? is there a fix that can be made that does not require me to redefine the function?有没有不需要我重新定义函数的修复方法? Is this unique to react?这是唯一的反应吗?

As @Tuhin pointed out, the short answer is closures.正如@Tuhin 指出的,简短的回答是闭包。 When you define setF(()=>function(){console.log(val)}) , val = 0 and at no point after that is the function definition changed, so f has closure over the value of val at the point of its creation.当您定义setF(()=>function(){console.log(val)}) , val = 0 并且在此之后的任何时候都不会更改函数定义,因此f在点处对 val 的值具有闭包它的创造。 You can add console.dir(f) in your code to check it out:您可以在代码中添加console.dir(f)来查看: 图片

In your code, f didn't update when val updated.在您的代码中,当val更新时f没有更新。 If you give to your useEffect the val as a dependency the problem will be solved.如果您将val作为依赖项提供给useEffect ,则问题将得到解决。 You can see it .你可以看到

As I understood, you want to print recent val by the f function.据我了解,您想通过f函数打印最近的val

But The problem is, setF(()=>function(){console.log(val)}) <-- this line.但问题是, setF(()=>function(){console.log(val)}) <-- 这一行。

val will be always 0 as it is assigned once, and will be called by value, not by the reference. val 将始终为 0,因为它被分配一次,并且将通过值调用,而不是通过引用调用。 Just like how setTimeout works.就像 setTimeout 的工作原理一样。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM