这是我参与2022首次更文挑战的第25天,活动详情查看:2022首次更文挑战
大家好,我是前端西瓜哥。今天说说 React Hooks 的 useRef。
Refs,是关联引用的意思,是 React 提供的一种让我们可以访问 DOM 节点或 React 元素的一种机制。
类组件中使用 ref
类组件通过 creatRef 创建 ref,然后作为 DOM 元素或类组件的 ref 属性。当组件被渲染后,对应的 ref 就能通过属性 current 拿到 DOM 元素或组件实例。
需要注意的是,绑定的 React 元素必须为类组件,这样我们才能通过实例来获取熟悉或调用一些方法。如果是函数组件,就会报错,因为函数组件不提供实例对象。
我们看看下面的类函数使用 ref 的例子。
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.inputRef = React.createRef();
this.componentRef = React.createRef();
}
componentDidMount() {
console.log(this.inputRef.current);
console.log(this.componentRef.current);
}
render() {
return (
<div>
<input ref={this.inputRef} type="text" />
{/* Button 为类组件 */}
<Button ref={this.componentRef}></Button>
</div>
);
}
}
控制台输出为:
函数组件中使用 ref
后来 React Hooks 带着它的 useRef 出现了,让我们也可以在组件函数使用 ref。
const myRef = useRef(null);
我们拿到一个 current 属性为 null 的 ref 对象。在之后的任意一次渲染,ref 对象都是指向的都是同一个对象。
上面的类组件示例,改成函数组件就是下面这样子的:
function TextInput() {
const inputRef = useRef(null);
const componentRef = useRef(null);
useEffect(() => {
console.log(inputRef.current);
console.log(componentRef.current);
}, [])
return (
<div>
<input ref={inputRef} type="text" />
{/* Button 为类组件 */}
<Button ref={componentRef}></Button>
</div>
);
}
函数组件的 “实例属性”
其实你可以把函数组件的 ref 对象看作类似类组件实例属性的存在。于是函数组件的 ref 对象获得了全新的能力:模拟类组件实例属性。
如果你想在函数组件声明一个每次渲染都不改变的对象,且修改这个对象,不会引发组件的重新渲染,Refs 是很好的一个选择。
下面看一个使用 useRef 和 useEffect 简单实现类组件 ComponentDidUpdate :
const isMounted = useRef(false);
useEffect(() => {
if (!isMounted.current) return;
console.log('更新');
// 业务代码
});
useEffect(() => {
console.log('挂载');
isMounted.current = true;
}, []);
当然最好还是封装一下,做成自定义 hook 会更好些,你可以实现一下。