• 第33节——useRef


    一、概念

    useRef,他的作用是“勾住”某些组件挂载完成或重新渲染完成后才拥有的某些对象,并返回该对象的引用。该引用在组件整个生命周期中都固定不变,该引用并不会随着组件重新渲染而失效。返回一个可变的 ref 对象,该对象只有个 current 属性,初始值为传入的参数( initialValue )。返回的 ref 对象在组件的整个生命周期内保持不变。当更新 current 值时并不会 re-render ,这是与 useState 不同的地方。更新 useRef 是 side effect (副作用),所以一般写在 useEffect 或 event handler 里。useRef 类似于类组件的 this

    const refContainer = useRef(initialValue);
    
    • 1

    二、useRef是来解决什么问题的

    1、JSX组件转换后对应的真实DOM对象。如何获取input的真实dom

    useRef只适合“勾住”小写开头的类似原生标签的组件。如果是自定义的react组件(自定义的组件必须大写字母开头),那么是无法使用useRef(当然也有一些奇淫技巧后面我们后续课程会讲😈)的。比如,我们如何获取这个 真实DOM呢。那么就可以使用useRef

    初始化input聚焦
    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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    2、在useEffect中创建的变量,如何在useEffect 以外的地方,获取并引用

    例子

    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
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    4、父组件调用子组件内的方法

    注意:除非情况非常特殊,否则一般情况下都不要采用 父组件调用子组件的函数 这种策略

    实现思路

    父组件中通过 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;
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    子组件
    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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    三、useRef与createRef的区别

    1、useRef是针对函数组件的,如果是类组件则使用React.createRef()。

    2、React.createRef()也可以在函数组件中使用。useRef只能在react hooks中使用

    3、createRef每次都会返回个新的引用;而useRef不会随着组件的更新而重新创建

  • 相关阅读:
    Docker
    [附源码]计算机毕业设计医学图像管理平台Springboot程序
    gRPC之gateway集成swagger
    k8s卷管理-2
    【SpringCloud】2-SpringCloud微服务架构实例-订单支付
    JavaScript 处理数组函数的总结
    数据结构之单链表
    【tio-websocket】9、服务配置与维护—TioConfig
    【大数据】HDFS的使用与集群角色(学习笔记)
    论文详解 GLENet 增强型3D目标检测网络
  • 原文地址:https://blog.csdn.net/weixin_57017198/article/details/132994018