reactjs - 使用 React hooks 和 memo 时如何防止子组件重新渲染?

标签 reactjs react-hooks

我刚刚开始尝试 React hooks,我想知道如何防止子组件在父组件重新渲染时重新渲染。我正在寻找类似于在 componentDidUpdate 中返回 false 的内容。我的问题似乎源于我在子组件中调用以更改父组件中的状态的单击处理程序。由于该函数是在父组件中创建的,因此它是在每个父渲染上创建的,这会触发子组件中的 Prop 更改,然后导致子组件重新渲染(我认为)。这是一些示例代码来帮助说明情况。

function Parent() {
    const [item, setItem] = useState({ name: "item", value: 0 });

    const handleChangeItem = () => {
        const newValue = item.value + 1;
        setItem({ ...item, value: newValue });
    };

    return <Child item={item} changeItem={handleChangeItem} />;
}

const Child = React.memo(function Child({ item, changeItem }) {
    function handleClick(){
        changeItem();
    }
    return (
        <div>
            Name: {item.name} Value: {item.value}
            <button onClick={handleClick}>change state in parent</button>
        </div>
    );
});

如何防止每次父组件渲染时子组件都渲染?父级中的 handleChangeItem 是否应该位于其他位置,以便不会在每次渲染时重新创建它?如果是这样,它如何访问 useState 返回的 itemsetItem

我对 react 还很陌生,刚刚开始使用 hooks,所以我可能错过了一些明显的东西。

最佳答案

在您的情况下,记住 Child 并没有真正意义,因为如果项目发生更改,则 child 必须重新渲染。但是,如果存在 props 没有更改的情况,但由于重新创建函数,子级仍然重新渲染,您将使用 useCallback用于在每次渲染时记住函数的钩子(Hook)。此外,由于您已经记住了处理程序,因此您应该使用回调方法来更新状态,因为处理程序内的 item 仅引用该函数最初创建时的值

function Parent() {
  const [item, setItem] = useState({ name: "item", value: 0 });

  const handleChangeItem = useCallback(() => {
    setItem(prevItem => ({ ...prevItem, value: prevItem.value + 1 }));
  }, []);

  return (
    <>
      Name: {item.name} Value: {item.value}
      <Child changeItem={handleChangeItem} />
    </>
  );
}

const Child = React.memo(function Child({ item, changeItem }) {
  function handleClick() {
    changeItem();
  }
  console.log("child render");
  return (
    <div>
      <button onClick={handleClick}>change state in parent</button>
    </div>
  );
});

Working demo

附注 Credit to @danAbramov for the direction

关于reactjs - 使用 React hooks 和 memo 时如何防止子组件重新渲染?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54015086/

相关文章:

reactjs - 为什么抛出错误的 React 组件会渲染两次?

javascript - React - SetState 处理程序方法

javascript - 无法从 Google Place Search API 返回的 JSON 中提取数据

javascript - 如果 props 改变,React 会重新评估 useRef

reactjs - 多层 forwardRef 和 useImperativeHandle

javascript - 在Wordpress中执行 Jest 测试时,如何修复import {}意外 token

css - 如何在 Semantic-UI-React 中使表格可滚动?使用 Next.js

javascript - 你能用 React hooks 提前回来吗?

javascript - 为什么我的组件在没有严格模式的情况下渲染两次?

javascript - JSON 服务器 - 将数据发布到数组中的特定对象中