📅  最后修改于: 2023-12-03 15:40:53.886000             🧑  作者: Mango
useRef
是 React 提供的一个 hook 函数,用于创建一个可以在组件的生命周期中持久化的引用。通常情况下,我们会使用 useRef
创建一个组件的引用,然后在需要的时候直接使用该引用来访问组件的 DOM 元素,并进行相关操作。
但是,useRef
还有一个非常重要的用途,那就是用于处理差异。在 React 中,当组件状态发生变化时,React 会比较前后状态的差异,然后重新渲染组件。这个过程中,React 会进行一系列优化,包括直接复用之前渲染过的 DOM 元素,而不是重新创建一份。但是,当我们需要直接去修改 DOM 元素,或者进行一些需要操作 DOM 元素的操作时,就需要避免 React 的复用优化,强制使用新的 DOM 元素。这个时候,useRef
就可以发挥作用了。
useRef
的基本用法非常简单,只需要调用该函数并传入初始化值即可:
const myRef = useRef(initialValue);
返回的 myRef
对象包含了一个 current
属性,用于存储组件的引用。之后可以直接使用 myRef.current
来访问该引用。
通常情况下,我们在使用 useEffect
时,会传入一个依赖数组,React 会通过比较这个数组的值来判断是否需要重新运行该 useEffect
里的代码。如果数组中的值发生变化,就会重新运行,否则就跳过。但是,当我们需要强制使用新的 DOM 元素时,就需要在依赖数组中加入一个不变的值,这个值可以使用 useRef
来存储。
举个例子,假设我们有一个组件需要在初始化时添加一个 click 事件监听器:
import { useRef, useEffect } from 'react';
function MyComponent() {
const ref = useRef();
useEffect(() => {
ref.current.addEventListener('click', handleClick);
return () => {
ref.current.removeEventListener('click', handleClick);
};
}, [ref]);
function handleClick() {
console.log('click!');
}
return <div ref={ref}>My Component</div>;
}
但是,如果我们同时需要在该组件的一个状态变化时,强制使用新的 DOM 元素,那么就需要在 useEffect
的依赖数组中加入一个不变的值,比如 ref
,这样就可以每次都使用新的 DOM 元素:
import { useRef, useEffect, useState } from 'react';
function MyComponent() {
const ref = useRef();
const [count, setCount] = useState(0);
useEffect(() => {
ref.current.addEventListener('click', handleClick);
return () => {
ref.current.removeEventListener('click', handleClick);
};
}, [ref, count]);
function handleClick() {
console.log('click!');
}
return (
<div ref={ref}>
My Component
<button onClick={() => setCount(count + 1)}>Click Me</button>
</div>
);
}
此时,每次 count
的值发生变化时,useEffect
都会重新运行一次,而且由于 ref
在每次渲染时都保持不变,因此每次都会使用不同的 DOM 元素。
useRef
的本质是创建一个可以在组件的生命周期中持久化的引用,并且可以在需要访问组件的 DOM 元素时直接使用该引用。此外,useRef
还可以用于处理差异,强制使用新的 DOM 元素。有了这个知识,我们就可以更加灵活地处理组件的状态和 DOM 元素了!