所以我目前有一个如下所示的组件:
<Parent>
<Child/>
</Parent>
但是,有时我只想返回:
<Child/>
这可以这样做:
if (condition) {
return <Child/>
}
return (
<Parent>
<Child/>
</Parent>
)
问题是当
condition
满足(true)时<Child/>
将重新渲染。遗憾的是,<Child/>
内的任何道具/状态都没有改变,并且该组件的渲染成本可能相当昂贵。
我不想重写
<Parent/>
,这样它所需要的就成为<Child/>
的兄弟,因为这是一个很大的改变。
每次满足
<Child/>
时,我该如何停止这种不必要的 condition
渲染。
我尝试过使用
React.memo
,但它没有按照我的预期工作。
不幸的是,我认为您想要实现的目标是不可能的,但是您可以使用类似的功能来解决问题。这样想:不要添加和删除子级(父级)的包装器,而是尝试添加和删除兄弟级。这几乎是同样的事情。我知道您说过您不想修改
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;
您尝试过 useMemo 吗?
const child = useMemo(()=><Child/>,[])
if(condition) return child;
//...