介绍:
react的 useRef
挂钩是一种强大的工具,由于其独特的行为而经常使新移民感到困惑。与状态变量不同,修改 useRef
对象的 current
属性不会触发组件重新呈现。此外, useRef
表现出非凡的能力。在本综合指南中,我们将探讨为什么 useRef
以这种方式行事,其背后的技术基础以及实际用例。让我们踏上掌握 useRef
的旅程。
关闭: useref 的基石
要理解为什么 useRef
保持状态并避免重新租赁,我们必须首先掌握JavaScript中关闭的概念。闭合允许功能记住并访问其词汇范围的变量,即使在该范围之外执行时也可以从其词汇范围中访问。在 useRef
的背景下,封闭是维持跨订单的参考的关键。
考虑 useRef
的简化实现:
function useRef(initialValue) {
const refObject = {
current: initialValue,
};
return refObject;
}
在此实现中,当前属性位于 refObject
(JavaScript对象)中。至关重要的是, refObject
可作为封闭,捕获和保存 current
跨重新租赁的属性。
在重新租赁期间,React不会为 refObject
创建新的关闭。相反,它利用了参考 refObject
的现有关闭。这种行为确保对 current
的变化持续存在。
不变性和反应渲染
要欣赏为什么 useRef
不会触发重新订阅者,我们必须深入研究React的渲染机制及其对不变性的依赖。 REACT的作用是基于以下原理:当它检测到组件的状态或道具的变化时,它会重新呈现分量。
但是, useRef
对象的 current
可以在而无需触发重新渲染的情况下修改属性。考虑此示例:
import React, { useRef } from 'react';
function MyComponent() {
const myRef = useRef(null);
const handleButtonClick = () => {
// Modifying the current property doesn't trigger a re-render
myRef.current.textContent = 'Button Clicked';
};
return (
<div>
<button onClick={handleButtonClick}>Click Me</button>
<p ref={myRef}>Initial Text</p>
</div>
);
}
在此示例中,当单击按钮时,修改了 textContent
of myRef.current
。值得注意的是,这种变化不会导致组件重新渲染。为什么?因为 myRef
对象本身保持不变。
反应依赖于先前和电流值的比较来确定是否需要重新渲染。由于 myRef
对象的身份或参考在我们更新其 current
属性时不会改变,因此React不会将其视为触发的状态或道具更改重新渲染。
反应的身份与和解
要完全掌握为什么 useRef
在重新订阅中保持一致,我们需要探索React的和解过程。 React使用对帐来确定组件是否应更新。它通过将新的虚拟DOM(vdom)与上一个。
当react确定组件或元素的身份(在这种情况下,参考)没有更改时,它会考虑相同并跳过重新渲染。此过程对于React的性能优化策略至关重要。
整个渲染的一致性
反应非常强调 current
属性的一致性, useRef
对象遍布渲染。通过在初始渲染期间仅创建一次 useRef
对象来确保这种一致性。随后的渲染重复使用相同的对象。因此,对 current
属性的任何更改都持续存在。
这种一致性是 useRef
的强大功能,因为它允许开发人员在渲染之间保持状态,而不会引起不必要的重新汇款。无论您是存储对DOM元素的引用还是回忆值, useRef
都提供了一种可靠且性能的机制来实现这一目标。
实际应用和最佳实践:
除了了解 useRef
的内部运作之外,探索其实际应用和最佳实践至关重要。
1.访问和操纵DOM元素:
useRef
经常用于直接与DOM元素相互作用。当您需要执行诸如专注于输入字段,滚动到特定元素或动画元素之类的操作时,这一点特别有用。
import React, { useRef } from 'react';
function MyComponent() {
const inputRef = useRef(null);
const handleFocusButtonClick = () => {
// Focus on the input element using useRef
inputRef.current.focus();
};
return (
<div>
<input ref={inputRef} type="text" />
<button onClick={handleFocusButtonClick}>Focus Input</button>
</div>
);
}
2.存储可变值没有重新租赁:
与状态变量不同,更改为 useRef
对象的 current
属性不会触发重新订阅者。这使得 useRef
是存储不会影响组件UI但需要在渲染之间持续存在的值的绝佳选择。
import React, { useState, useEffect, useRef } from 'react';
function MyComponent() {
const [count, setCount] = useState(0);
const previousCountRef = useRef(0);
useEffect(() => {
// Update the previous count when count changes
previousCountRef.current = count;
}, [count]);
return (
<div>
<p>Current Count: {count}</p>
<p>Previous Count: {previousCountRef.current}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
3.优化性能:
useRef
也可以成为优化性能的宝贵工具。您可以使用它来记忆昂贵的计算,以确保仅在必要时重新计算它们。
import React, { useState, useEffect, useRef } from 'react';
function MyComponent() {
const [inputValue, setInputValue] = useState('');
const [result, setResult] = useState(null);
const computationCache = useRef({});
useEffect(() => {
if (!computationCache.current[inputValue]) {
// Perform the expensive calculation and store the result in the cache
computationCache.current[inputValue] = performExpensiveCalculation(inputValue);
}
// Update the result with the cached value
setResult(computationCache.current[inputValue]);
}, [inputValue]);
return (
<div>
<input
type="text"
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
/>
<p>Result: {result}</p>
</div>
);
}
结论:
总而言之, useRef
是React开发人员工具包中的多功能工具。通过利用封闭,不变性和React的对帐过程, useRef
在不触发不必要的更新的情况下维护整个重新汇款的状态。了解这些机制使开发人员有反应,以建立高效,响应和性能的应用。无论您是使用DOM元素,记忆价值还是优化性能, useRef
都是您开发旅程中的宝贵资产。掌握它为增强您的编码技巧和反应应用程序的用户体验开辟了一个可能性。