基本用法
- 在类组件中获取一个dom元素实例,可以通过React.CreateRef或者回调函数的方式去获取。
- 语法:
const refContainer = useRef(initialValue);
- 使用场景:在 React 中进行 DOM 操作时,用来获取 DOM
- 作用:返回一个带有 current 属性的可变对象,通过该对象就可以进行 DOM 操作了。
const inputRef = useRef(null)
解释:
- 参数:在获取 DOM 时,一般都设置为 null
- 返回值:包含 current 属性的对象。
- 注意:只要在 React 的函数组件中进行 DOM 操作,都可以通过 useRef Hook 来获取 DOM(比如,获取 DOM 的宽高等)。
- 注意:useRef不仅仅可以用于操作DOM,还可以操作组件
通过useRef获取DOM元素或组件实例:
import React from 'react'
import {useRef} from 'react'export default function UseRef() {let inputRef = useRef()function login() {console.log(inputRef.current.value)}return (<div><input ref={inputRef} placeholder={'请输入账号'} /><button onClick={login}>登录</button></div>)
}
绑定ref后,和React.createRef返回的结构一致,通过.current
获取到元素。
useRef保存数据
在文件中定义一个全局变量保存数据
存在 bug
UseRef.jsx
import {useRef, useState} from "react";let count = 0;export default function UseRef() {console.log('ref')let inputRef = useRef()function login() {count += 1;}function printCount() {console.log(count)}return (<div><input ref={inputRef} placeholder={'请输入账号'} /><button onClick={login}>登录</button><button onClick={printCount}>打印count</button></div>)
}
这种全局保存变量的方式,有问题,原因在于在组件中多次使用这个组件会共享数据,可能会导致一些bug存在。
import UseRef from './components/UseRef'export default function App() {return (<div><UseRef /><UseRef /></div>)
}
在函数组件中直接定义变量
存在 bug
import {useRef, useState} from "react";export default function UseRef() {let count = 0;console.log('ref')let inputRef = useRef()let [name, setName] = useState('张三')function login() {count += 1;}function printCount() {console.log(count)}return (<div><input ref={inputRef} placeholder={'请输入账号'} /><button onClick={login}>登录</button><button onClick={printCount}>打印count</button>姓名:{name}<button onClick={() => setName('李四')}>修改name</button></div>)
}
这种方式可以短暂的保存值,但是一旦函数组件更新渲染,那么这个变量的值就会重置
原因是因为函数组件更新渲染时,代码从上往下重新运行。
使用useRef保存值
在整个生命周期里ref里存储的都是同一个,这样就可以----
解决闭包陷阱问题
import {useRef, useState} from "react";export default function UseRef() {// let count = 0;let count = useRef(0);console.log('ref')let inputRef = useRef()let [name, setName] = useState('张三')function login() {// console.log(inputRef.current.value)count.current += 1;}function printCount() {console.log(count.current)}return (<div><input ref={inputRef} placeholder={'请输入账号'} /><button onClick={login}>登录</button><button onClick={printCount}>打印count</button>姓名:{name}<button onClick={() => setName('李四')}>修改name</button></div>)
}
通过useRef
保存值,可以长期存贮,不会重置
使用useRef定义变量的好处:
- 修改state后ref保存的数据不会变化
- 多个组件的数据,不会共享,类似于class的实例字段
- 修改ref的保存值,不会引起组件的更新渲染。