React hooks文档笔记(四) useRef

useRef

当想让组件记住一些信息,又不想触发新的渲染,可以使用ref:总是返回同一个对象。

1. state 和 refs 的比较

refs(普通的 JavaScript 对象)

state

更改时不触发重新渲染

更改时触发重新渲染

可变的——修改/更新current’s value

(修改完立即生效

 ref.current = 5;

  console.log(ref.current); // 5

不可变——必须使用state的setting函数去修改state变量

React 状态的限制(每个渲染的快照,不会同步更新)

useRef(initialValue)  returns

{ current: initialValue }

useState(initialValue) returns ( [value, setValue])

每次更新state,组件会重新渲染

import { useState } from 'react';

export default function Counter() {
  const [count, setCount] = useState(0);
  function handleClick() {
    setCount(count + 1);
  }
  return (
    <button onClick={handleClick}>
      You clicked {count} times
    </button>
  );
}

 ref.current不要在渲染过程中读取或写入,组件不会随着每次ref增量而重新渲染:

import { useRef } from 'react';

export default function Counter() {
  let countRef = useRef(0);
  function handleClick() {
    // This doesn't re-render the component!
    countRef.current = countRef.current + 1;
  }
  return (
    <button onClick={handleClick}>
      You clicked {countRef.current} times
    </button>
  );
}

2. 常见使用场景

A. 存储timeout IDs

import { useRef } from 'react';

export default function Chat() {
  let timeoutID = useRef(null);

  function handleSend() {
    timeoutID.current = setTimeout(() => {
      alert('Sent!');
    }, 3000);
  }

  function handleUndo() {
    clearTimeout(timeoutID.current);
  }
}

B. 存储和操纵dom元素(避免更改由 React 管理的 DOM 节点)

  • 基础用法: <div ref={counterRef} />

  • 访问其他组件的dom节点:

import { forwardRef, useRef } from 'react';

const MyInput = forwardRef((props, ref) => {

//(可选)限制公开的内容,不让Form组件的ref调用处理其他事件(如修改css)
  const realInputRef = useRef(null);
  useImperativeHandle(ref, () => ({
    // Only expose focus and nothing else
    focus() {
      realInputRef.current.focus();
    },
  }));

  return <input {...props} ref={ref} />;
});

export default function Form() {
  const inputRef = useRef(null);

  function handleClick() {
    inputRef.current.focus();
  }

  return (
    <>
      <MyInput ref={inputRef} />
      <button onClick={handleClick}>
        Focus the input
      </button>
    </>
  );
}

 C. 存储其他对计算jsx非必要的对象