为什么 useState 不替换旧值?

Val*_*llo 0 reactjs react-hooks

我注意到,如果我使用用作 useState 初始值设定项的新值重新渲染组件,则返回的值将从之前的渲染中缓存,而不是用新值替换。我怎样才能避免这种行为?

最小的例子:

import React, { useState } from "react";
import ReactDOM from "react-dom";

class App extends React.Component {
  render() {
    return <Test />;
  }
}

ReactDOM.render(<App />, document.getElementById("container"));

function Test() {
  const [val, setVal] = useState();
  setTimeout(() => {
    setVal(5);
  }, 1000);
  return <Cached value={val}></Cached>;
}

function Cached({ value }) {
  console.log({ value });
  const [val] = useState(value || "cached");
  console.log({ val });
  return <p>{val}</p>;
}
Run Code Online (Sandbox Code Playgroud)

https://codesandbox.io/s/react-playground-forked-1ykk3?file=/index.js

如果您检查控制台,value并且val有不同的值,我希望它们是相同的。但 UI 只打印"cached"

Kei*_*ter 6

这是因为当您初始化状态时:

const [val] = useState(value || "cached");
Run Code Online (Sandbox Code Playgroud)

value未定义。那是因为它是在父组件中设置的超时。由于子组件在超时完成之前渲染并value更新为 5,因此它保持“缓存”状态(这是因为useState只会初始化一次)。为了更新状态以反映正在传递的 props,您需要使用一个useEffect以 value 作为依赖项的钩子。这样你就可以更新状态以反映道具的变化。

function Cached({ value }) {
  const [val, setVal] = useState(value ? value : "cached");
  
  useEffect(() => {
    setVal(value);
  }, [value]);

  return <p>{val}</p>; // will update to 5 once prop changes
}
Run Code Online (Sandbox Code Playgroud)