大家好,我是前端西瓜哥。今天说说 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 会更好些,你可以实现一下。