useRef,他的作用是“勾住”某些组件挂载完成或重新渲染完成后才拥有的某些对象,并返回该对象的引用。该引用在组件整个生命周期中都固定不变,该引用并不会随着组件重新渲染而失效。返回一个可变的 ref 对象,该对象只有个 current 属性,初始值为传入的参数( initialValue )。返回的 ref 对象在组件的整个生命周期内保持不变。当更新 current 值时并不会 re-render ,这是与 useState 不同的地方。更新 useRef 是 side effect (副作用),所以一般写在 useEffect 或 event handler 里。useRef 类似于类组件的 this
const refContainer = useRef(initialValue);
useRef只适合“勾住”小写开头的类似原生标签的组件。如果是自定义的react组件(自定义的组件必须大写字母开头),那么是无法使用useRef(当然也有一些奇淫技巧后面我们后续课程会讲)的。比如,我们如何获取这个 真实DOM呢。那么就可以使用useRef
import React,{useEffect,useRef} from 'react'
function Component() {
//先定义一个inputRef引用变量,用于“勾住”挂载网页后的输入框
const inputRef = useRef(null);
useEffect(() => {
//inputRef.current就是挂载到网页后的那个输入框,一个真实DOM,因此可以调用html中的方法focus()
inputRef.current.focus();
},[]);
return
{/* 通过 ref 属性将 inputRef与该输入框进行“挂钩” */}
}
export default Component
1、组件中有一个变量count,当该组件挂载到网页后,count每秒自动 +1。
2、组件中有一个按钮,点击按钮可以停止count自动+1
import React,{useState,useEffect,useRef} from 'react'
function Component() {
const [count,setCount] = useState(0);
const timerRef = useRef(null);//先定义一个timerRef引用变量,用于“勾住”useEffect中通过setIntervale创建的计时器
useEffect(() => {
//将timerRef.current与setIntervale创建的计时器进行“挂钩”
timerRef.current = setInterval(() => {
setCount((prevData) => { return prevData +1});
}, 1000);
return () => {
//通过timerRef.current,清除掉计时器
clearInterval(timerRef.current);
}
},[]);
const clickHandler = () => {
//通过timerRef.current,清除掉计时器
clearInterval(timerRef.current);
};
return (
{count}
)
}
export default Component
注意:除非情况非常特殊,否则一般情况下都不要采用 父组件调用子组件的函数 这种策略
父组件中通过 useRef 定义一个钩子变量,例如 childFunRef
父组件通过参数配置,将 childFunRef 传递给子组件
子组件在自己的 useEffect() 中定义一个函数,例如 doSomting()
划重点:一定要在 useEffect() 中定义 doSomting(),不能直接在子组件内部定义。
因为如果 doSomting() 定义在子组件内部,那么就会造成每一次组件刷新都会重新生成一份 doSomthing()
然后将 doSomting() 赋值到 childFunRef.current 中
这样,当父组件想调用子组件中的 doSomting() 时,可执行 childFunRef.current.doSomting()
import { useRef } from "react";
import ChildComponent from "./child";
const ParentComponent = () => {
const childFunRef = useRef();
const handleOnClick = () => {
if (childFunRef.current) {
childFunRef.current.doSomething();
}
};
return (
);
};
export default ParentComponent;
import { useEffect, useState } from "react";
const ChildComponent = ({ funRef }) => {
const [num, setNum] = useState(0);
useEffect(() => {
const doSomething = () => {
setNum(Math.floor(Math.random() * 100));
};
funRef.current = { doSomething }; //在子组件中修改父组件中定义的childFunRef的值
}, [funRef]);
return {num};
};
export default ChildComponent;
1、useRef是针对函数组件的,如果是类组件则使用React.createRef()。
2、React.createRef()也可以在函数组件中使用。useRef只能在react hooks中使用
3、createRef每次都会返回个新的引用;而useRef不会随着组件的更新而重新创建