Live2D

React学习笔记(八) userRef

相信有过React使用经验的人对ref都会熟悉,它可以用来获取组件实例对象或者是DOM对象。

useRef这个hooks函数,除了传统的用法之外,它还可以“跨渲染周期”保存数据

在一个组件中有什么东西可以跨渲染周期,也就是在组件被多次渲染之后依旧不变的属性?第一个想到的应该是state。没错,一个组件的state可以在多次渲染之后依旧不变。但是,state的问题在于一旦修改了它就会造成组件的重新渲染。

那么这个时候就可以使用useRef来跨越渲染周期存储数据,而且对它修改也不会引起组件渲染。

看下面一个例子

import React, { useState, useEffect } from 'react'

function App() {
  const [count, setCount] = useState(0)

  useEffect(() => {
    setTimeout(() => {
      console.log("count: " + count)
    }, 3000)
  }, [count])

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>增加 count</button>
    </div>
  );
}

export default App

当点击四次增加按钮后,控制台会打印0,1,2,3,4

当我们用ref保存数据后

import React, { useRef } from 'react'

function App() {
  const count = useRef(0);

  const showCount = () => {
    console.log("count: " + count.current);
  };

  const handleClick = number => {
    count.current = count.current + number;
    setTimeout(showCount, 3000);
  };

  return (
    <div>
      <p>You clicked {count.current} times</p>
      <button onClick={() => handleClick(1)}>增加 count</button>
      <button onClick={() => handleClick(-1)}>减少 count</button>
    </div>
  );
}

export default App

点击四次增加,控制台会打印 4 4 4 4.

再看下传统的用法

import React, { useEffect, useCallback, useState, useRef } from 'react'

export default function RefComponent() {
  const [count, setCount] = useState(0)

  let x = useRef(true)
  let y = useRef(null)

  useEffect(() => {
    if (x.current) {
      x.current = false
    } else {
      console.log(0)
      console.log(y.current)
    }
  })

  const handleClick = useCallback(
    () => {
      setCount(5000)
    },
    [],
  )

  return (
    <div ref={y}>
      hello {x.a} - {count}
      <button onClick={handleClick}>click</button>
    </div>
  )
}

代码中用userRef创建了两个对象x和y。x用于保存状态,y赋给了divref属性,x用于在首次加载组件时不会打印y绑定的DOM对象,点击click按钮更改count数据页面刷新,会打印0和y绑定的DOM对

posted @ 2021-08-24 16:40  吃完夜宵再睡觉  阅读(418)  评论(1)    收藏  举报