为什么React在这种情况下渲染子级? (状态相同,使用useState)

时间:2020-06-15 01:10:36

标签: reactjs

Code Sandbox

import React, { useState, useEffect } from "react";

const Foo = () => {
  console.log("render foo");
  return <div> foo</div>;
};

const App = () => {
  const [value, setValue] = useState(1);

  useEffect(() => {
    console.log("effect", value);
  }, [value]);

  console.log("rendering");
  return (
    <div>
      {" "}
      <Foo /> <button onClick={() => setValue(value)}>Click To Render</button>
    </div>
  );
};

export default App;

现在按照React Documentation

如果将状态挂钩更新为与当前状态相同的值,React将纾困而不渲染子代或发射效果(重点是我的) (React使用Object.is比较算法。)

请注意,React可能仍需要再次渲染该特定组件,然后才能发布。不必担心,因为React不会不必要地“深入”到树中。如果渲染时要进行昂贵的计算,则可以使用useMemo优化它们。

在我给出的示例中,我们可以看到useEffect挂钩没有触发,如文档所述,但是我的Foo组件正在渲染。

这是为什么?

我认为内联函数可能会导致渲染-但是如果我使用useCallback将其更改为记忆函数,则会发生相同的行为:

  const handleClick = useCallback(() => setValue(value), [value]);

  console.log("rendering");
  return (
    <div>
      {" "}
      <Foo /> <button onClick={handleClick}>Click To Render</button>
    </div>

1 个答案:

答案 0 :(得分:2)

bail out逻辑是在react-dom v16.8.0中实现的,其中react也引入了钩子,而您的演示使用钩子的alpha版本,这就是为什么即使在更新为时仍会触发重新渲染的原因相同状态

根据v16.8.0发行说明

  • 避免对useState和useReducer Hooks使用相同的值进行渲染。 (@acdlite在#14569中)

Edit FORM VALUES