- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在一个相对较大的 React 代码库上工作,我看到以前的开发人员大量使用 memo
和 usecallback
并认为通过使用它们可以提高性能。显然不是,这里有一个例子
export default function QuestionHelper({ text }: { text: string }) {
const [show, setShow] = useState<boolean>(false);
const open = useCallback(() => setShow(true), [setShow]);
const close = useCallback(() => setShow(false), [setShow]);
return (
<span style={{ marginLeft: 4 }}>
<Tooltip show={show} text={text}>
<QuestionWrapper
onClick={open}
onMouseEnter={open}
onMouseLeave={close}
>
<Question size={16} />
</QuestionWrapper>
</Tooltip>
</span>
);
}
该应用程序现在可以正常工作。但是我拒绝修复它,因为该应用程序按预期工作。我怎样才能证明我们应该删除代码中所有不必要的 memo
和 usecallback
?
是否有一种客观的方式来说明去除这些的好处?
最佳答案
因此,删除示例中的那个实际上可能会改变一些事情。如果您使用 useCallback
内存它,那么 open
函数会在渲染之间持续存在,这意味着该函数在每个渲染周期都在内存中保持相同的位置。如果你删除它并且刚刚拥有
const open = () => setShow(true);
然后每次组件渲染时,都会重新创建此函数,从而在内存中有一个新位置。
这意味着什么?好吧,假设您的 QuestionWrapper
组件导出是用 React.memo
包装的,因为不必要的重新渲染可能会导致该特定组件出现性能问题。那么当比较 functions 和 ===
时,Javascript 如何比较对象(函数在技术上是 JS 中的对象)?它进行“引用比较”,即比较两个输入在内存中的地址,看它是否是同一个对象。在当前代码中,当使用 useCallback
内存时,引用不会在重新呈现之间更改。但是如果你删除它,那么它的引用将在每次重新渲染时改变,并且 React.memo
将不再适用于 QuestionWrapper
因为它会认为它每次都会获得一个新对象时间,即使实际功能及其逻辑永远不会改变。
现在,也许在您的应用程序中这无关紧要,也许 QuestionWrapper
可以重新渲染很多次而不会出现性能问题,或者也许该组件没有被内存,所以这无关紧要,但总的来说,要点是:不要尝试重构/优化不会导致问题的事情,除非不会有大的影响做。
在理想情况下,您会评估这种情况,是的,从技术上讲,删除一些内存可能是最佳选择。然而在真实世界中,您继承的代码库充满了不理想的废话,但您只是出于多种原因使用它,例如:
以及其他各种原因。我知道次优的东西可能有点烦人,我们希望我们的代码 super 流畅、结构良好和优化,但不幸的是,我们必须面对这样一个现实,即在大型、真实世界的应用程序中,代码通常是充满了这样的东西。其中一些可能只是其他开发人员的懒惰或无知,或者其中一些实际上可能是出于一个可能不会立即显而易见的充分理由。
你总是可以自由表达担忧,但除非你非常有经验并且完全理解这种重构的含义,并且确实没有更好的事情可做,那么如果每个人都说保持原样,最好这样做。几乎可以肯定,你的时间有更好的用途,如果你做了一些事情,比如不小心破坏了应用程序或引入了错误,只是为了进行微小的优化或修复甚至不会引起任何问题的事情,你会让自己变得很不受欢迎。
此外,根据我使用 React 的经验,bug 很重要。记忆化可能会导致奇怪的行为,因此很难追踪。
关于reactjs - 我应该删除 React 应用程序中所有不必要的 usecallback 和 memo 用法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71613152/
我正在尝试通过容器将 Redux mapStateToProps() 和 mapActionCreators() 连接到登录屏幕,并且我正在使用 React 导航。 构建我的应用程序后,出现以下错误消
你能告诉我为什么我的标题每次渲染都已经使用了 React.memo 吗? 当我从 导航时,我有两个部分 my app and user我的应用程序 到 user header 重新呈现为什么? 这是我
我正在尝试在 React 应用程序中插入 google maps map 。我宁愿不使用非官方图书馆(我发现那些缺乏文档的图书馆),而且我已经成功地插入了 map 。 我的问题是每次父组件的状态改变时
我有一个父组件,它根据通过 props 接收到的数组来渲染子组件的集合。 import React from 'react'; import PropTypes from 'prop-types';
我只是使用 redux 和react-redux connect 函数以及状态和调度来连接应用程序。编译没有问题,但结果没有显示。如下所示。 我尝试查找,发现必须更换react版本。 $ sudo n
我习惯了export default React.memo(SomeComponent);所以 React 可以内存我的组件。 但是在我使用命名导出的文件中。如何使用 React.memo() ? e
我正在创建一个函数备忘录,返回一个函数,该函数在调用时将检查它是否已经计算出给定参数的结果,并在可能的情况下返回该值。 现在我的 key 仅包含作为我的 key 传入的第一个参数,以检查该函数是否已经
考虑以下简单组件: import React, { Fragment, memo } from 'react'; function Parent(props) { return (
我的父组件处理对服务器的请求并为其子组件提供来自响应的数据。在这种情况下,一个子组件(FilterSidebar:包含过滤器组件)应该只呈现一次,因为过滤器将从初始请求的数据创建。 这就是为什么我要使
是否可以将 React.memo 应用于带有 for 循环的组件数组? 假设我有以下三个组件: const Item1 = (props) => { const { index } = pro
我到处搜索有关此信息,似乎Access中的DAO参数限制为255个字符。 真的吗?仍然?即使在Office 2010中?看来很荒谬。我宁愿不切换到ADO,但在这一点上看来我必须这样做。 在仍然使用DA
每次我的选项卡组件父组件重新呈现时,我的子组件也会重新呈现。 我的标签组件父级如下 import { useState } from "react"; import "./styles.scss";
我正在重构我们的一些组件,所以我试图将 memoization 作为一些组件合并 5 月 使用相同的值重新渲染(例如,热链接图像 URL,除非它们相同)。 我有一个简单的组件: const CardH
我不想在某些路径上重新渲染我的组件,尝试使用 React.memo 并使用 withRouter HOC 检查当前路径。 React.memo 中的比较函数没有被调用。 function compar
我使用 React 前端制作了一个国际象棋游戏。最初,任何 Action 似乎都是瞬间实现的,但是在添加了额外的功能之后,比如改变标题的背景以反射(reflect)轮到谁了(白色或黑色背景取决于它的白
我正在尝试制作一个聊天应用程序,它将以如下形式将消息发布到备忘录中: USERNAME-> Message 但它像这样发布到我的备忘录中: USERNAME 这是我的代码: const cnMax
在 documentation for React.memo ,它说: This method only exists as a performance optimization. Do not re
有人知道当使用react-redux中的connect函数时如何用React.memo包装React组件吗? 例如,您将如何修改以下内容? let Button = (props: Props) =>
以下代码来自 Pathikrit's Dynamic Programming存储库。 我对它的美丽和独特性感到困惑。 def subsetSum(s: List[Int], t: Int) = {
我正在使用 Apollo GraphQL 中的 useMutation Hook ,并且我想使用 onCompleted 属性执行特定任务。基本上,我想在 useMutation 成功完成时执行 se
我是一名优秀的程序员,十分优秀!