useRef 简单易懂解析(十)你学会了吗,来试试这些挑战 - 读取最新状态

655 阅读2分钟

这是我参与11月更文挑战的第7天,活动详情查看:2021最后一次更文挑战

当你希望组件“记住”一些信息,但是你不希望这些信息触发重新 render 的时候,你可以使用 ref,它像一个秘密的“口袋”,用于在组件中存储信息。

后面的文章主要是通过一些例子检验对 ref 的理解,实际在 react 官方博客上可以执行调试,文章主要是分析,可以对照着看:beta.reactjs.org/learn/refer…

系列文章

读取最新状态

挑战 4(共 4 个):读取最新状态

在本例中,当你按下“发送”键后,在显示提示消息之前会有一个小的延迟。输入 “hello”,按发送,在提示消息还没出来之前,再次快速编辑输入。尽管你进行了编辑,提示会显示 “hello”(这是单击按钮时候的状态值)。

通常,这种行为是你在应用程序中想要的。然而,有时你可能想要一些异步代码读取某些状态的最新版本。你能想出一种方法让提示显示当前输入的文本,而不是点击时的文本吗?

import { useState, useRef } from 'react';

export default function Chat() {
  const [text, setText] = useState('');

  function handleSend() {
    setTimeout(() => {
      alert('Sending: ' + text);
    }, 3000);
  }

  return (
    <>
      <input
        value={text}
        onChange={e => setText(e.target.value)}
      />
      <button
        onClick={handleSend}>
        Send
      </button>
    </>
  );
}

3

2

1

state 就像快照一样工作,因此你无法从超时等异步操作中读取最新的 state。但是,您可以在 ref 中保留最新的输入文本。ref 是一个可变纯对象的,因此你可以随时读取它的 current 属性,由于当前文本也用于在输入框渲染,所以在本例中,你将需要一个 state(用于渲染)和一个 ref(在超时时读取它)。您需要手动更新当前的 ref 值。

import { useState, useRef } from 'react';

export default function Chat() {
  const [text, setText] = useState('');
  const textRef = useRef(text);  // 这里

  function handleChange(e) {
    setText(e.target.value);
    textRef.current = e.target.value;  // 这里
  }

  function handleSend() {
    setTimeout(() => {
      alert('Sending: ' + textRef.current); // 这里
    }, 3000);
  }

  return (
    <>
      <input
        value={text}
        onChange={handleChange}
      />
      <button
        onClick={handleSend}>
        Send
      </button>
    </>
  );
}