reactjs 当父组件改变时,如何停止不必要的子组件重新渲染

acruukt9  于 5个月前  发布在  React
关注(0)|答案(2)|浏览(76)

所以我现在有一个看起来像这样的组件:

<Parent>
<Child/>
</Parent>

字符串
然而,有时我只想返回:<Child/>
可以这样做:

if (condition) {
return <Child/>
}

return (
<Parent>
<Child/>
</Parent>
)


问题是当condition被满足(true)时,<Child/>将重新渲染。这是一个耻辱,因为<Child/>内部的props/state没有改变,而且这个组件的渲染成本可能相当高。
我不想重写<Parent/>,因为这是一个很大的变化,所以它所需要的东西就变成了<Child/>的兄弟。
我如何在每次满足condition时停止<Child/>的这种不必要的渲染。
我试过使用React.memo,但它并没有像我预期的那样工作。

dwbf0jvd

dwbf0jvd1#

你试过useMemo吗?

const child = useMemo(()=><Child/>,[])

if(condition) return child;

//...

字符串

piv4azn7

piv4azn72#

不幸的是,我不认为你试图实现的是可能的,但是你可以做一个类似功能的解决方案。这样想:不要添加和删除子组件(父组件)的 Package 器,而是尝试添加和删除兄弟组件。这几乎是一回事。我知道你说过你不想修改Parent组件的代码,但是我不认为这会影响你的代码。
下面是一个示例:

const Parent = ({
  children,
  state,
}: {
  children: ReactNode;
  state: number;
}) => {
  return (
    <>
      {state % 2 === 0 ? (
        <>
          <label>Sibling 1</label>
          <div>Sibling 2</div>
        </>
      ) : (
        ""
      )}
      {children}
    </>
  );
};

字符串
正如你所看到的,我并没有修改所有的东西,只是添加和删除了兄弟组件。另外,记住将useMemo添加到子组件中:

const Child = () => {
  const [childState, setChildState] = useState<number>(0);

  return useMemo(() => {
    console.log("Child re-render");
    return (
      <button
        onClick={() => {
          setChildState(childState + 1);
        }}
      >
        Child State: {childState}
      </button>
    );
  }, [childState]);
};


在这个例子中,只有当childState被修改时,子组件才应该重新渲染。如果来自父组件的状态被修改,那么只有兄弟组件应该被渲染。下面是我的完整代码:

import { ReactNode, useMemo, useState } from "react";

const App = () => {
  const [appState, setAppState] = useState<number>(0);

  return (
    <>
      <button
        onClick={() => {
          setAppState(appState + 1);
        }}
      >
        test
      </button>
      <Parent state={appState}>
        <Child />
      </Parent>
    </>
  );
};

const Parent = ({
  children,
  state,
}: {
  children: ReactNode;
  state: number;
}) => {
  return (
    <>
      {state % 2 === 0 ? (
        <>
          <label>Sibling 1</label>
          <div>Sibling 2</div>
        </>
      ) : (
        ""
      )}
      {children}
    </>
  );
};

const Child = () => {
  const [childState, setChildState] = useState<number>(0);

  return useMemo(() => {
    console.log("Child re-render");
    return (
      <button
        onClick={() => {
          setChildState(childState + 1);
        }}
      >
        Child State: {childState}
      </button>
    );
  }, [childState]);
};

export default App;

相关问题