为什么使用自定义钩子渲染组件会重新渲染App组件。如果我切换<Comp> or <AnotherComp>
,则整个App组件将与其他组件一样重新呈现。
我尝试了React.memo并将组件再次包装在App组件中,但是没有效果。
我读到它的反应方式比较并认为函数是不同的渲染器。但是人们是否为此目的使用了高级模式?
export const useCard = (params)=>{
const { ToBeWrappedComponent } = params;
const [isOpen,setIsOpen] = useState(true);
const toggle= ()=> setIsOpen(!isOpen);
const WrappedComponent = ()=>{
return (
<Collapse isOpen={isOpen} >
<button onClick= {toggle}> </button>
<ToBeWrappedComponent />
</Collapse>
)
}
return [WrappedComponent,toggle]
};
const App = ()=>{
const [Comp, toggleComp] = useCard({ToBeWrappedComponent: ()=> (<h1>Wrapped Item <h1>) });
const [AnotherComp, toggleAnotherComp] = useCard({ToBeWrappedComponent: ()=> (<h1>Another Wrapped Item <h1>) })
return (
<AnotherComp > </AnotherComp>
<Comp> </Comp>
)
}
请注意,这段代码只是我创建的一个示例,用来说明我所面临的问题,我使用此方法进行了更复杂的操作,并且只想了解实现它的高级模式及其渲染的原因。谢谢
答案 0 :(得分:1)
实际上是在App组件的函数中调用了useState
的调用:
const [isOpen,setIsOpen] = useState(true);
因此它成为App
状态的一部分,而不是包装组件状态的一部分。
组件会重新渲染,因为每次重新渲染App时,都会重新创建WrappedComponent
函数。它是具有不同地址的不同功能,因此从头重新渲染了组件树。
这是您正在使用的一种非常奇怪的模式。您真的使事情复杂化了。为什么不简单地将render函数传递给包装器组件?
const TogglableComponent = ({ renderWrappedComponent, isOpen, onClick }) => {
return (
<Collapse isOpen={isOpen} >
<button onClick={onClick} />
{ renderWrappedComponent() }
</Collapse>
)
};
然后,您可以通过道具从其父级控制每个组件的切换状态。或者,如果您不在乎将切换状态传递给父组件,只需将其存储在包装器中即可:
const TogglableComponent = ({ renderWrappedComponent }) => {
const [isOpen, setIsOpen] = React.useState(false);
return (
<Collapse isOpen={isOpen} >
<button onClick={() => setIsOpen(!isOpen)} />
{ renderWrappedComponent() }
</Collapse>
)
};