React中useRef钩子的使用技巧
创作时间:
作者:
@小白创作中心
React中useRef钩子的使用技巧
引用
1
来源
1.
https://developer.aliyun.com/article/1629174
在React中,useRef是一个非常有用的Hook,它可以让你在组件的生命周期内保留一些数据,而不会引起组件的重新渲染。本文将从基础概念入手,逐步深入到useRef的常见问题、易错点及如何避免这些问题,并通过代码示例来帮助理解其应用场景和实现方式。
基础概念
什么是useRef?
useRef是一个React Hook,它返回一个可变的ref对象,其.current属性被初始化为传递的参数(initialValue)。返回的ref对象在组件的整个生命周期内保持不变。
基本用法
import React, { useRef } from 'react';
function TextInputWithFocusButton() {
const inputEl = useRef(null);
const onButtonClick = () => {
// `current` 指向已挂载到 DOM 上的文本输入元素
inputEl.current.focus();
};
return (
<>
<input ref={inputEl} type="text" />
<button onClick={onButtonClick}>Focus the input</button>
</>
);
}
export default TextInputWithFocusButton;
在这个例子中,useRef用于获取对输入框的引用,以便在按钮点击时将其聚焦。
常见问题与易错点
1. 误用useRef来存储状态
useRef不应该用来存储组件的状态。React提供了useState和useReducer来管理状态,而useRef主要用于保存那些不需要触发重新渲染的数据。
错误示例
import React, { useRef, useEffect } from 'react';
function Counter() {
const countRef = useRef(0);
useEffect(() => {
countRef.current++;
});
return (
<div>
Count: {countRef.current}
</div>
);
}
export default Counter;
在这个例子中,countRef用于存储计数器的值,但由于countRef的变化不会触发重新渲染,因此界面上的计数器值不会更新。
正确示例
import React, { useState, useEffect } from 'react';
function Counter() {
const [count, setCount] = useState(0);
useEffect(() => {
setCount(prevCount => prevCount + 1);
}, []);
return (
<div>
Count: {count}
</div>
);
}
export default Counter;
2. 忘记初始化ref
在使用useRef时,忘记初始化ref可能会导致undefined错误。
错误示例
import React, { useRef } from 'react';
function Example() {
const myRef = useRef();
useEffect(() => {
console.log(myRef.current.value); // 可能会抛出错误
}, []);
return (
<input ref={myRef} type="text" />
);
}
export default Example;
正确示例
import React, { useRef, useEffect } from 'react';
function Example() {
const myRef = useRef(null);
useEffect(() => {
console.log(myRef.current?.value); // 使用可选链操作符
}, []);
return (
<input ref={myRef} type="text" />
);
}
3. 在函数组件中使用ref
在函数组件中使用ref时,需要确保正确地传递ref。
错误示例
import React, { useRef } from 'react';
function CustomInput(props) {
return <input {...props} />;
}
function App() {
const inputRef = useRef(null);
return (
<CustomInput ref={inputRef} />
);
}
export default App;
正确示例
import React, { useRef, forwardRef } from 'react';
const CustomInput = forwardRef((props, ref) => {
return <input ref={ref} {...props} />;
});
function App() {
const inputRef = useRef(null);
return (
<CustomInput ref={inputRef} />
);
}
export default App;
如何避免这些问题
- 明确用途:
useRef用于保存那些不需要触发重新渲染的数据,不要用它来管理状态。 - 初始化ref:始终初始化ref,避免
undefined错误。 - 使用可选链操作符:在访问ref的属性时,使用可选链操作符(
?.)来防止潜在的undefined错误。 - 正确传递ref:在自定义组件中使用
forwardRef来正确传递ref。
进阶用法
1. 保存回调函数
useRef可以用于保存回调函数,以避免在每次渲染时都创建新的函数引用。
import React, { useRef, useEffect } from 'react';
function UseRefCallbackExample() {
const callbackRef = useRef(null);
useEffect(() => {
callbackRef.current = handleScroll;
});
const handleScroll = () => {
console.log('Scrolled');
};
useEffect(() => {
window.addEventListener('scroll', callbackRef.current);
return () => {
window.removeEventListener('scroll', callbackRef.current);
};
}, []);
return (
<div>
Scroll down to see the effect.
</div>
);
}
export default UseRefCallbackExample;
2. 保存定时器ID
useRef可以用于保存定时器ID,以便在组件卸载时清除定时器。
import React, { useRef, useEffect } from 'react';
function TimerExample() {
const timerIdRef = useRef(null);
useEffect(() => {
timerIdRef.current = setInterval(() => {
console.log('Tick');
}, 1000);
return () => {
clearInterval(timerIdRef.current);
};
}, []);
return (
<div>
Timer is running...
</div>
);
}
export default TimerExample;
总结
useRef是一个非常强大的Hook,可以帮助你在组件的生命周期内保留一些数据,而不会引起组件的重新渲染。通过本文的介绍和代码示例,希望你能更好地理解和应用useRef,并在实际开发中避免常见的问题和易错点。
热门推荐
元旦换头像,趣味漫画脸让你与众不同!
储能系统:企业降本增效的新利器
四年级语文课上的心理健康魔法
陈更带你学四年级古诗词:品味经典,感受文化之美
寒假必读:四年级语文下册经典文章推荐
肩周炎来袭?这些拉伸动作帮你轻松缓解!
四年级学生如何应对“负面情绪”
川藏线自驾游,这些检查你做了吗?
《富贵逼人太盛》:一部古装剧的“咸鱼”逆袭之路
寻找舌尖记忆 最是河海交界咸鲜味
吴谨言婚讯背后:娱乐圈隐婚现象的心理解码
斗罗大陆最强神器:修罗魔剑的恐怖实力解析
冷风吹疼了你的左膀子?试试这些妙招!
左膀子疼?当心误诊误治!
血脂高也有了管理指南,看看今后该怎么吃
93岁陈院士研究血脂多年,除了肉,这2种蔬菜尽量少吃
换机油时,选5W-30还是5W-40好?看完你就懂了!
机油更换的判断标准是什么?这种判断对发动机维护有何影响?
校园安全教育:如何保护孩子?
科学饮水:苏打水的真相揭秘
小苏打水真能缓解胃酸吗?专家:效果有限,这些人要慎喝
苏打水真能治百病吗?科学解读来了
让过年成为一种“方法”
五一云游建水碗窑村:千年紫陶探秘之旅
五一云游建水碗窑村,感受千年紫陶文化
拉萨自驾游的最佳季节揭秘!
安徽省妇幼保健院专家:备孕二胎家庭健康管理全攻略
大北农VS远东控股:谁的生育奖励政策更给力?
向阳生涯教你30岁职场逆袭秘籍
三十岁如何保持心理健康?从时间管理到重启人生