为啥 useRef 值在它是整数时会动态更新,但在它是字符串时会存储先前的值?

Posted

技术标签:

【中文标题】为啥 useRef 值在它是整数时会动态更新,但在它是字符串时会存储先前的值?【英文标题】:Why useRef value dynamically updates when it is an integer but stores the previous value when it is a string?为什么 useRef 值在它是整数时会动态更新,但在它是字符串时会存储先前的值? 【发布时间】:2021-10-29 18:36:32 【问题描述】:

我刚刚学习了 useRef 并且对它的实际工作原理感到困惑。例如, #1

function Ref() 
  const rerenderCount = useRef(0);

  useEffect(() => 
    rerenderCount.current = rerenderCount.current + 1;
  );

  return <div>rerenderCount.current</div>;

这里,useRef 给出的输出与下面代码中的 useState 相同,#2

function State() 
  const [rerenderCount, setRerenderCount] = useState(0);

  useEffect(() => 
    setRerenderCount(prevCount => prevCount + 1);
  );

  return <div>rerenderCount</div>;

但是在这个#3 代码中,previousName.current 值总是显示前一个值。但它被设置为名称。

const [name, setName] = useState("");
  const previousName = useRef(null);

  useEffect(() => 
    previousName.current = name;
  , [name]);

  return (
    <div className="App">
      <input value=name onChange=(e) => setName(e.target.value) />
      <div>
        My name is name and it used to be previousName.current
      </div>
    </div>
  );

请有人解释为什么这个名字在整数按时更新的地方倒退了一步。另外,useEffect 中 [name] 的用途是什么。无论有没有它,我都会得到相同的结果和渲染计数。

【问题讨论】:

[name] in useEffect 是一个依赖项。在此数组中,您声明了一个依赖项列表,并且当其中至少一个更改时,执行 useEffect 中的代码。代码也在第一次渲染时运行。因此,每次在输入文本中键入内容时,您都会更改 previousName.current。如果你不添加任何依赖,useEffect 将在每次组件重新渲染时运行。 @Antonio 能否解释一下为什么 perviousName.current 总是在名称后面加一个字母?就像我输入'abcd'.. name = 'abcd' 但是 perviousName.current = 'abc'?它在 useEffect 里面,所以当名称更新时为什么 useRef 不是? 【参考方案1】:

在您的示例中,previousName 落后了一步,因为当您更改 name 状态时,组件将重新渲染,调用 useEffect 并更新 previousName,但最后的更改不会导致新的渲染( useRef 与 useState 不同,组件不会重新渲染),因此您会看到 name 正确更新,但 previousName 的值与以前相同,即使其值已更改。 这是因为previousName的变化是在后续渲染过程中由于状态的变化而发生的。 要看到它的变化,需要额外的渲染。 为避免这种行为,您可以使用事件处理程序而不是依赖 useEffect 挂钩。

const handleChange = (text: string) => 
    setName(text);
    previousName.current = text;
  ;

  return (
    <div className="App">
      <input value=name onChange=(e) => handleChange(e.target.value) />
      <div>
        My name is name and it used to be previousName.current
      </div>
    </div>
  );

【讨论】:

我现在明白了,谢谢。 如果您可以接受并且认为它可能对其他人有帮助,请考虑将其接受。

以上是关于为啥 useRef 值在它是整数时会动态更新,但在它是字符串时会存储先前的值?的主要内容,如果未能解决你的问题,请参考以下文章

为啥此查询在 ODBC 表上运行但在本地表上运行时会失败?

为啥在尝试调用采用动态参数的基本构造函数/方法时会出现此编译错误?

为啥整数类缓存值在 -128 到 127 范围内?

为啥当我输入整数数据时,它的值在 Codeigniter 中总是四舍五入

为啥我的十进制值在 SQL 插入中被四舍五入为整数?

为啥这种带有动态输入值的表单验证不起作用?