当前位置: 首页 > 面试题库 >

使用react-hooks在每个渲染上创建处理程序的性能损失

单于越
2023-03-14
问题内容

目前,我对新的react hooks API
的用例以及您可能会做的事情感到非常惊讶。

实验时出现的一个问题是,总是创建一个新的处理函数仅在使用时就扔掉是多么昂贵useCallback

考虑以下示例:

const MyCounter = ({initial}) => {
    const [count, setCount] = useState(initial);

    const increase = useCallback(() => setCount(count => count + 1), [setCount]);
    const decrease = useCallback(() => setCount(count => count > 0 ? count - 1 : 0), [setCount]);

    return (
        <div className="counter">
            <p>The count is {count}.</p>
            <button onClick={decrease} disabled={count === 0}> - </button>
            <button onClick={increase}> + </button>
        </div>
    );
};

尽管我将处理程序包装为,useCallback以避免每次渲染新处理程序时都会传递新的处理程序,但仍然必须创建内联箭头函数,而在大多数情况下都必须将其丢弃。

如果我只渲染几个组件,可能没什么大不了的。但是,如果我这样做数千次,对性能的影响有多大?有明显的性能损失吗?避免这种情况的方法是什么?可能是仅在必须创建新处理程序时才调用的静态处理程序工厂?


问题答案:

阵营常见问题 给它提供一个解释

挂钩是否由于在render中创建函数而变慢?

不。在现代浏览器中,闭包的原始性能与类相比没有什么显着差异,除非在极端情况下。

此外,请考虑Hooks的设计在几种方面更有效:

挂钩避免了类所需的大量开销,例如在构造器中创建类实例和绑定事件处理程序的开销。

使用Hooks的惯用语代码不需要使用高阶组件,渲染道具和上下文的代码库中普遍存在的深层组件树嵌套。使用较小的组件树,React要做的工作更少。

传统上,与React中的内联函数有关的性能问题与子组件中的ComponentUpdate优化如何在每个渲染中断处传递新的回调有关。挂钩从三个方面解决了这个问题。

因此,钩子提供的总体收益远大于创建新功能所带来的损失

此外,对于功能组件,您可以通过使用进行优化,useMemo以便在其道具没有变化的情况下重新渲染组件。



 类似资料:
  • 问题内容: 我正在学习React,并按照本教程创建了一个简单的Tic- Tac-Toe游戏,您可以在CodePen中查看。 对于在Board组件的函数内部返回的Square组件的属性中的箭头功能如何工作,我感到困惑。同样,我拥有的游戏组件也同样如此。我以为我可以不用箭头功能(就像一样)来编写它,但这会中断游戏。 问题答案: 期望功能。箭头函数没有自己的功能; 使用封闭执行上下文的值。箭头功能可替代

  • 我通过以下命令启动了新的React项目: 然后,我将App组件更改为这样: 当我查看控制台日志(在Google Chrome和Microsoft Edge中)时,我会收到以下消息: 我的问题: 为什么要调用两次应用程序渲染 如何删除带有该WDS的第一封邮件? 这是我的(默认为我运行的):

  • 问题内容: 我以TodoList为例来反映我的问题,但是显然我的实际代码更加复杂。 我有一些这样的伪代码。 我所有的数据都是不可变的,并且使用了并且一切正常。修改待办事项数据后,仅 重新渲染父项和已编辑的待办事项。 问题是,随着用户的滚动,我的列表有时会变得很大。并且,当更新单个待办事项时,渲染 父项,调用shouldComponentUpdate所有待办事项以及渲染单个待办事项所花费的时间越来越

  • 我最近在处理(http://processing.org/)我希望知道是否有一个库可以帮助我创建两个不同的窗口来渲染同一场景的两个视图。还有什么方法可以直接从一个切换到另一个。

  • 问题内容: 我正在尝试使用新的Hooks从类组件转变为功能组件。但是,感觉与类组件中的类函数不同,我将获得不必要的子代渲染。 下面有两个相对简单的片段。第一个是我的示例编写为类,第二个是我的示例重写为功能组件。目的是使功能组件获得与类组件相同的行为。 类组件测试用例 功能组件测试用例 在第一个(类组件)中,我可以通过红色块更新计数,而无需重新渲染任何一个块,并且我可以通过橙色块自由地控制台记录当前

  • 我为我的草图创建了一个简单的延迟函数,并试图使用它,但似乎渲染停止了,也就是说,有一个简单的灰色屏幕,然后一切都被一次渲染。 有人能告诉我我在哪里吗出错了?到底发生了什么? 如何在内部定义绘制()和设置()?我知道,set()是一个一次性的渲染和绘制(),就像一个无限的循环。 代码: