反应回调避免为孩子重新渲染

时间:2021-03-15 14:33:50

标签: javascript reactjs react-hooks

我很难避免重新渲染。 看看我的简化示例:https://codesandbox.io/s/gracious-satoshi-b3p1u?file=/src/App.js 打开控制台。我在过滤大数组的子钩子中有昂贵且繁重的代码(不在这个轻量级示例中)。 每次“孩子已被渲染”被打印到控制台时,如果我经常这样做,我的浏览器就会滞后并崩溃。

Child 中没有状态。如果我单击需要回调进行通信的文本区域,我只是使用它来添加某个文本片段(用户可以从一个大的表情符号和特殊字符列表中进行选择)。我尝试了 React.useMemo()useMemo(),但都没有奏效。

2 个答案:

答案 0 :(得分:0)

您应该使用 useCallback 来记忆函数/事件处理程序并避免每次都创建它们,并且对于子组件,您应该使用 memo 仅在 props 更改时重新渲染

App.js

import React, { useCallback, useState } from "react";
import Child from "./Child";

export default function App() {
  const [data, setData] = useState({ title: "default title", test: null });
  const cb1 = useCallback(
    (x) => setData({ ...data, title: x.target.value }),
    []
  );
  const cb2 = useCallback((x) => setData({ ...data, test: x }), []);

  return (
    <div>
      <p>Title: {data.title}</p>
      <p>Test: {data.test}</p>

      <input onChange={cb1} />
      <Child clickCallback={cb2} />
    </div>
  );
}

Child.js

import { memo } from "react";

export default memo(function Child(props) {
  return (
    <>
      {console.log("child has been rendered")}
      <button onClick={() => props.clickCallback("test")}>test</button>
      <button onClick={() => props.clickCallback("test2")}>test2</button>
      <button onClick={() => props.clickCallback("test3")}>test3</button>
      <button onClick={() => props.clickCallback("test4")}>test4</button>
    </>
  );
});

在这里查看一个工作示例https://codesandbox.io/s/vibrant-curran-tv502

答案 1 :(得分:0)

试试这个。根据需要添加 useMemo 依赖项,

export default function App() {
  const [data, setData] = useState({ title: "default title", test: null });

  const childs = useMemo(() => {
    return (
      <Child clickCallback={(x) => setData({ ...data, test: x })} />
    )
  }, []);

  return (
    <div>
      <p>Title: {data.title}</p>
      <p>Test: {data.test}</p>

      <input onChange={(x) => setData({ ...data, title: x.target.value })} />
      {childs}
    </div>
  );
}