小编典典

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

reactjs

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

该示例表明,如果我们想获取最新的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;

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


阅读 778

收藏
2020-07-22

共1个答案

小编典典

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>
  );
}

编辑Q-57444154-封闭

2020-07-22