美文网首页react
React hooks之useRef

React hooks之useRef

作者: 修齐治平zzr | 来源:发表于2021-09-28 13:49 被阅读0次
    react hooks之effect、state篇,在hooks中组件挂载时开启定时器时,我们通常需要用一个变量去保存定时器id方便组件卸载时清除。
    正常想法下是这样写的:
    import React,{ useEffect, useState } from 'react';
    
    function demo() {
      let timer;
      const [list, setList] = useState([]);
    
      const getList = () => {
        // 获取数据
      }
      // 第一次请求
      useEffect(() => {
        getList();
      }, [])
      // 30s后开始轮询
      useEffect(() => {
          timer = window.setInterval(() => {
          getList();
        }, 30000)
        return () => window.clearInterval(timer); // 此处一定要return出一个函数
       }, [])
      
      return (
         // <>dom</>
      )
    }
    

    浏览器会报warning:

    Assignments to the 'timer' variable from inside React Hook useEffect will be lost after each render. To preserve the value over time, store it in a useRef Hook and keep the mutable value in the '.current' property. Otherwise, you can move this variable directly inside useEffect react-hooks/exhaustive-deps

    意思如下

    每次渲染后,从React Hook Useffect内部对“timer”变量的指定将丢失。要随时间保留该值,请将其存储在useRef hook中,并将可变值保留在“.current”属性中。

    这个时候就需要引入useRef了
    React的官方文档是这样描述的:

    useRef 返回一个可变的 ref 对象,其 .current 属性被初始化为传入的参数(initialValue)。返回的 ref 对象在组件的整个生命周期内持续存在。

    特点如下:

    • 它可以很方便地保存任何可变值,其类似于在 class 中使用实例字段的方式。
    • 它创建的是一个普通 Javascript 对象。而 useRef() 和自建一个 {current: ...} 对象的唯一区别是,useRef 会在每次渲染时返回同一个 ref 对象。
    • 当 ref 对象内容发生变化时,useRef不会通知你。变更 .current 属性不会引发组件重新渲染。如果想要在 React 绑定或解绑 DOM 节点的 ref 时运行某些代码,则需要使用回调 ref 来实现。

    回到问题,使用useRef解决上述warning
    import React,{ useEffect, useState, useRef } from 'react';
    
    function demo() {
      const timerRef = useRef(null);
      const [list, setList] = useState([]);
    
      const getList = () => {
        // 获取数据
      }
      // 第一次请求
      useEffect(() => {
        getList();
      }, [])
      // 30s后开始轮询
      useEffect(() => {
          timerRef.current = window.setInterval(() => {
          getList();
        }, 30000)
        return () => window.clearInterval(timerRef.current); 
       }, [])
      
      return (
         // <>dom</>
      )
    }
    
    其他场景中,useRef还可以这样用。
    function App() {
      const rootRef = useRef(null)
    
      useEffect(() => {
        // rootRef.current.style.backgroundColor = 'red'; // 操作dom
        const p = document.createElement('p');
        p.innerHTML = "this is new p";
        rootRef.current.appendChild(p);
      }, [])
    
      return (
        <>
          <div ref={rootRef} className="App">
            <Root />
          </div>
        </>
      );
    }
    
    如果我们需要一个状态,而且这个状态的改变不能触发组件的render,例如:dom, 本地存储等等,那我们都可以使用ref对象去储存它。毕竟hooks是react的趋势。

    相关文章

      网友评论

        本文标题:React hooks之useRef

        本文链接:https://www.haomeiwen.com/subject/rpglnltx.html