使用 useMemo 在渲染期间更新 React Hooks 状态

eco*_*coe 10 render memoization reactjs react-hooks

useMemo被用来只是以避免额外的参考平等检查代码设置状态时/瓦尔期间渲染?

示例:从这个罕见的记录用例中获取useMemosetState期间渲染:

function ScrollView({row}) {
  let [isScrolling, setIsScrolling] = useState(false);

  const lessCodeThanCheckingPrevRow = useMemo(
    () => {
      // Row changed since last render. Update isScrolling.
      setIsScrolling(true); // let's assume the simplest case where prevState isn't needed here
    },
    [row]
  );

  return `Scrolling down: ${isScrolling}`;
}
Run Code Online (Sandbox Code Playgroud)

以上大大减少了代码和额外的变量,仅用于相等性检查,那么为什么文档暗示应该手动进行引用相等性检查?

tri*_*ixn 7

对我来说,这似乎是减少样板代码的一种优雅方式。我创建了一个codesandbox来验证它的行为。

const UnitUnderTest = ({prop}) => {
  let [someState, setSomeState] = useState(false);

  const lessCodeThanCheckingPrevRow = useMemo(
    () => setSomeState(current => !current), 
    [prop],
  );

  useEffect(() => console.log('update finished'), [prop])

  console.log('run component');

  return `State: ${someState}`;
}

const App = () => {
  const [prop, setProp] = useState(false);
  const handleClick = () => setProp(current => !current);

  return (
    <div>
      <button onClick={handleClick} >change prop</button>
      <UnitUnderTest prop={prop} />
    </div>
  )
};

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Run Code Online (Sandbox Code Playgroud)

编辑 recursing-hopper-4ynjm

单击按钮更改传递给组件的 prop 时的输出:

> run component 
> run component 
> update finished 
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,在更新周期完成之前该组件已运行两次。这相当于 的行为getDerivedStateFromProps

我猜想,为什么文档提出了一种略有不同的技术,背后并没有更深入的思考。在某种程度上,这也是手动检查,但方式很简洁。这个想法+1。