当前位置: 首页 > 面试题库 >

为什么需要useRef在组件函数之外包含可变变量而不定义变量?

段晨
2023-03-14
问题内容

我已经阅读了《使用效果的完全指南-过度反应应对潮流》。

该示例表明,如果我们想获取最新的count,我们可以使用useRef保存可变变量,并在异步函数laster中获取它:

function Example() {
  const [count, setCount] = useState(0);
  const latestCount = useRef(count);

  useEffect(() => {
    // Set the mutable latest value
    latestCount.current = count;
    setTimeout(() => {
      // Read the mutable latest value
      console.log(`You clicked ${latestCount.current} times`);
    }, 3000);
  });
  // ...
}

但是,我可以通过在组件函数外部创建一个变量来执行相同的操作,例如:

import React, { useState, useEffect, useRef } from 'react';

// defined a variable outside function component
let countCache = 0;

function Counter() {
  const [count, setCount] = useState(0);
  countCache = count;       // set default value

  useEffect(() => {
    setTimeout(() => {
      // We can get the latest count here
      console.log(`You clicked ${countCache} times (countCache)`);
    }, 3000);
  });
  // ...
}

export default Counter;

两种方法都可行,或者如果我在函数组件外部定义变量,有什么不好的方法吗?


问题答案:

useRef将为 每个 组件分配一个引用,而在函数组件外部定义的变量将仅被调用一次。

此外,尝试呈现countCache值将行不通:

let countCache = 0;

function Counter() {
  ...
  countCache = 0;

  useEffect(() => {
    countCache = count;
  });
  ...

  return <div>{countCache}</div>
}

由于使用了javascript闭包,因此参考可以按方面使用。

在下一个示例中,单击按钮时,您可能会注意到variable两个组件都是全局的,而reference总是按预期更新。

// defined a variable outside function component
let countCache = 0;

function Counter() {
  const [count, setCount] = useState(0);

  const countRef = useRef(count);

  useEffect(() => {
    // Update count on every render
    countCache = count;
    countRef.current = count;
  });

  return (
    <div>
      <button onClick={() => setCount(p => p + 1)}>click me</button>
      <h3>variable</h3>
      {countCache}
      <h3>reference</h3>
      {countRef.current}
    </div>
  );
}

export default function App() {
  return (
    <FlexBox>
      <FlexBox>
        <Counter />
      </FlexBox>
      <FlexBox>
        <Counter />
      </FlexBox>
    </FlexBox>
  );
}



 类似资料:
  • 如果我在我的类中创建一个bool,就像一样,它默认为false。 当我在我的方法中创建相同的bool时,我得到一个错误“使用未分配的局部变量检查”。为什么?

  • 问题内容: 在Python中的类上定义方法时,它看起来像这样: 但是在某些其他语言(例如C#)中,你可以使用“ this”关键字来引用该方法所绑定的对象,而无需在方法原型中将其声明为参数。 这是Python中的一种故意的语言设计决策,还是有一些实现细节需要传递“ self”作为参数? 问题答案: 我喜欢引用Peters的。“显式比隐式好。” 在Java和.可以推断出’ ‘,除非你拥有无法推断的变量

  • 问题内容: 如果一个元组是不可变的,那么为什么它可以包含可变项呢? 似乎矛盾的是,当可变项(例如列表)确实被修改时,它所属的元组保持不变。 问题答案: 这是一个很好的问题。 关键的见解是,元组无法知道其中的对象是否可变。使对象可变的唯一方法是拥有一种更改其数据的方法。通常,无法检测到此情况。 另一个见解是Python的容器实际上不包含任何东西。相反,它们保留对其他对象的引用。同样,Python的变

  • 问题内容: 在lambda中,局部变量需要是最终变量,而实例变量则不需要。为什么这样? 问题答案: 字段和局部变量之间的根本区别在于,当JVM创建lambda实例时,将复制局部变量。另一方面,字段可以自由更改,因为对它们的更改也将传播到外部类实例(它们的范围是整个外部类,如Boris所指出的)。 考虑到匿名类,闭包和Labmdas的最简单方法是从可变范围的角度来看。想象一个为传递给闭包的所有局部变

  • 下面的示例类无法编译: 此代码的编译错误消息是: 但是,对于包含以下方法的类,Java不会生成任何错误消息: 关于初始化及其要求,为什么Java对最终实例变量和最终局部变量的处理不同?谢谢

  • 变量绑定默认是不可变的,但加上 mut 修饰语后变量就可以改变。 fn main() { let _immutable_binding = 1; let mut mutable_binding = 1; println!("Before mutation: {}", mutable_binding); // 正确代码 mutable_binding += 1