gpt4 book ai didi

javascript - 为什么需要 useRef 而不是可变变量?

转载 作者:行者123 更新时间:2023-12-03 13:57:01 25 4
gpt4 key购买 nike

我已阅读A Complete Guide to useEffect - Swimming Against the Tide react 过度。

这个例子表明,如果我们想要获取最新的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 将为每个组件分配一个引用,而在函数组件范围之外定义的变量只会分配一次

useRef reference life span is component's life span (it "dies" when the component unmounts, while JS variables are scope-blocked).

因此,在组件范围之外定义常量目的变量:

// This statement will only called once
const DEFAULT_VALUE = 5;

function Component() {
// use DEFAULT_VALUE.
}

在组件范围内定义相同的语句,将在每次渲染时重新定义它:

// We can do better
function Component() {
// Redefined on every render
const DEFAULT_VALUE = 5;
}
<小时/>

现在问问题:

首先,我们实际上无法反射(reflect)使用外部作用域变量更改的 UI,因为更改它们不会触发渲染(只有 React API 会触发渲染)。

因此反射值为其closure值。

let countCache = 0;

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

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

// closure value of countCache
return <div>{countCache}</div>
}
<小时/>

现在,外部作用域变量的特殊之处在于它们对于模块本身来说是全局的,因此使用它的值对于引用它的所有组件(在模块中)来说是全局的。

For example if you want to count how many times the component mounted in your whole application life span, increase the variable inside useEffect on mount (couldn't find any other possible use-case).

let howMuchMounted = 0;

function Component() {
useEffect(() => { howMuchMounted += 1, [] };
}

为了反射(reflect)外部变量和 useRef 引用的差异,在下一个示例中,单击按钮时,您可能会注意到 变量 对于两个组件都是全局的,而引用始终更新为当前状态值。

import React, { useEffect, useRef, useReducer } from "react";
import ReactDOM from "react-dom";

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

function Counter() {
const [num, count] = useReducer((num) => num + 1, 0);

const countRef = useRef(count);

useEffect(() => {
// set count value on count change
countCache = num;
countRef.current = num;
}, [num]);

return (
<>
<button onClick={count}>Count</button>
<h3>state {num}</h3>
<h3>variable {countCache}</h3>
<h3>reference {countRef.current}</h3>
</>
);
}

export default function App() {
return (
<>
<Counter />
<hr />
See what happens when you click on the other counter
<hr />
<Counter />
</>
);
}
<小时/>

请参阅follow up question on useEffect use cases ,在 useEffect 内使用 useRef 引用时存在许多常见错误。

Edit useRef vs Variable

关于javascript - 为什么需要 useRef 而不是可变变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57444154/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com