useRef
将分配一个参考each组件,而在函数组件范围之外定义的变量只会分配一次.
useRef
引用生命周期是组件的生命周期(当组件卸载时它“死亡”,而 JS 变量是范围阻塞的)。
因此,在组件范围之外定义常量目的变量:
// 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;
}
现在问题是:
首先,我们实际上无法反映使用外部作用域变量更改的 UI,因为更改它们不会触发渲染(只有 React API 会触发渲染)。
因此反射值就是它的closure value.
let countCache = 0;
function Counter() {
...
countCache = 0;
useEffect(() => {
countCache = count;
});
...
// closure value of countCache
return <div>{countCache}</div>
}
现在,外部作用域变量的特殊之处在于它们对于模块本身来说是全局的,因此使用它的值对于引用它的所有组件(在模块中)来说是全局的。
例如,如果您想计算组件在整个应用程序生命周期内安装的次数,请增加内部变量useEffect
安装时(找不到任何其他可能的用例)。
let howMuchMounted = 0;
function Component() {
useEffect(() => { howMuchMounted += 1, [] };
}
反映外变量与useRef
参考,在下一个示例中,单击按钮时,您可能会注意到variable
对于两个组件来说都是全局的,而reference
始终更新为当前状态值。
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 />
</>
);
}
请看一个跟进问题useEffect用例,在使用时有很多常见的错误useRef
里面的参考文献useEffect
.