我有一个可以容纳多个<Accordion/>组件的<AccordionItem/>组件。我准备了一个这里的代码框演示。
当前的问题是,在初始呈现时,所有的<AccordionItem/>组件都呈现出来(检查代码框示例中的控制台日志)。因此,根据<Accordion/>组件用于呈现所有项的数组的大小,这意味着大量的初始呈现。另外,每次打开一个<AccordionItem/>时,都会重新呈现<AccordionItem/>中的所有项。为了性能考虑,这可能不是几个项目的问题。但是,在我的应用程序中,这可能是10个<AccordionItem/>组件,它们本身有一个嵌套的手风琴,每当用户打开一个组件时,就会不断地被重命名。因此,这可能意味着每次用户打开一个项时,都会发生50次重呈现。
我已经尝试了很多方法来消除这个问题。例如,手风琴依赖于active布尔值。因此,只有当这个active布尔值为真时,才能呈现手风琴的主体,这样就消除了问题,如下所示:
<div className="answer">{active && <AccordionBody />}</div>然而,下拉动画停止工作,身体没有完全打开。在维护漂亮的下拉动画的同时,我能做些什么来只呈现点击的<AccordionItem/>和它的身体呢?
发布于 2021-10-23 21:45:40
一般来说,当它需要改道时,你应该让它重新反应。
在AccordionBody组件的函数体中记录控制台是错误的,这是一个意外的副作用,然而,即使在将控制台日志移动到useEffect中(回想一下,每次呈现时调用useEffect钩子一次),在状态更新时,AccordionBody仍然作为Accordion组件的一部分重新命名faqs数组。
当状态或道具更新或其父组件重选器时,响应组件重命名器。当组件重排时,它必然会更改其整个组件子树(即其子树)。
这些额外的改道通常是便宜的,不一定是一个单独的问题。这实际上取决于被重命名的每个组件在重命名时所做的操作。不要过早地优化!
如果存在问题,可以用来帮助性能的工具是回忆录道具,即使用useMemo或useCallback来提供稳定的支持引用。
您还可以使用备忘录高阶组件来记忆组件。如果组件从相同的道具呈现相同的结果,则可以回溯所呈现的结果。在您的示例代码框中,这消除了重复的重发器。
AccordionBody
import React, { memo, useEffect } from "react";
function AccordionBody() {
useEffect(() => {
console.log("AccordionBody rendered"); // <-- log once per render
});
return (
<div>
<div>All of the AccordionBody's are rendered</div>
<div>So everytime an accordion item is openend</div>
<div>The AccordionBody component gets rendered 3 times</div>
<div>1 for every faq in the faqs array</div>
<div>How will this impact performance in a large array?</div>
<div>
How do I stop these recursive re-renders, while maintaining the
animation?
</div>
</div>
);
}
export default memo(AccordionBody); // <-- memoize render result
注意:不会过早地优化,但只在发现呈现或性能问题时才会进行优化。这通常是以个案为基础的。
https://stackoverflow.com/questions/69686185
复制相似问题