为什么 useRef 值是整数时动态更新,而当它是字符串时存储以前的值?

Why useRef value dynamically updates when it is an integer but stores the previous value when it is a string?

我刚刚学习了 useRef 并且对它的实际工作方式感到困惑。例如, #1

function Ref() {
  const rerenderCount = useRef(0);

  useEffect(() => {
    rerenderCount.current = rerenderCount.current + 1;
  });

  return <div>{rerenderCount.current}</div>;
}

此处,useRef 给出与以下代码中的 useState 相同的输出,#2

function State() {
  const [rerenderCount, setRerenderCount] = useState(0);

  useEffect(() => {
    setRerenderCount(prevCount => prevCount + 1);
  });

  return <div>{rerenderCount}</div>;
}

但在#3 代码中,previousName.current 值始终显示以前的值。但是设置为name.

const [name, setName] = useState("");
  const previousName = useRef(null);

  useEffect(() => {
    previousName.current = name;
  }, [name]);

  return (
    <div className="App">
      <input value={name} onChange={(e) => setName(e.target.value)} />
      <div>
        My name is {name} and it used to be {previousName.current}
      </div>
    </div>
  );

请有人解释为什么名称后退了一步,其中整数更新及时。另外,useEffect中的[name]有什么用。有或没有它,我得到相同的结果和渲染计数。

在您的示例中,previousName 落后了一步,因为当您更改 name 状态时,组件将重新渲染,调用 useEffect 并更新 previousName 但这是最​​后一次更改不会导致新的渲染(useRef 不像 useState,组件不会重新渲染),因此您会看到 name 已正确更新但 previousName 具有与以前相同的值,即使它的值已经改变。 这是因为state的变化导致后续渲染时发生了previousName的变化。 要查看其变化,需要额外的渲染。 为避免这种行为,您可以使用事件处理程序而不依赖于 useEffect 挂钩。

const handleChange = (text: string) => {
    setName(text);
    previousName.current = text;
  };

  return (
    <div className="App">
      <input value={name} onChange={(e) => handleChange(e.target.value)} />
      <div>
        My name is {name} and it used to be {previousName.current}
      </div>
    </div>
  );