问题标签 [usecallback]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
reactjs - React hooks - 向 useCallback/useEffect 添加详尽的依赖会导致无限循环
这已经在这里和这里得到了回答,但是在遵循解决方案后我仍然遇到同样的问题。
使用react-beautiful-dnd
. showMap
是一个布尔值,当单击按钮时从父组件传递。所做showMap
的就是
- 将 3 列网格变为 5,反之亦然
- 重新排列网格上的项目
我注释掉了里面的依赖useEffect
,useCallback
因为一旦它们被添加进去,我就会得到一个无限循环。
这是为什么?
注意:当useCallback
有一个空的依赖数组并且我记录fakeTrips
里面的更新useEffect
值是正确的。让我绊倒的是,如果这个警告在某个地方出现问题,该怎么办。我也想知道为什么会这样。
这些是我看到的警告。
reactjs - React:在 useEffect 中调用上下文函数时防止无限循环
在我的反应应用程序中,我正在渲染<Item>
组件的不同实例,我希望它们在上下文中注册/取消注册,具体取决于它们当前是否已安装。
我正在使用两个上下文(ItemContext
提供注册项目,ItemContextSetters
提供注册/注销功能)来执行此操作。
组件应在<Item>
安装或更改时注册自己,props.data
并在卸载时取消注册。所以我认为可以通过以下方式非常干净地完成useEffect
:
完整示例请参阅此代码框
现在,问题是这给了我一个无限循环,我不知道如何做得更好。循环是这样发生的(我相信):
- 一个
<Item>
电话registerItem
- 在上下文中,
items
被改变,因此registerItem
被重建(因为它取决于[items]
- 这会触发更改,
<Item>
因为itemContextSetters
已更改并useEffect
再次执行。 - 还执行了先前渲染的清理效果!(如此处所述:“React 还会在下次运行效果之前清理上一次渲染中的效果”)
- 这再次
items
在上下文中改变 - 等等 ...
我真的想不出一个可以避免这个问题的干净解决方案。我是否滥用了任何钩子或上下文 api?useEffect
关于如何编写组件在其-body和useEffect
-cleanup中调用的此类注册/注销上下文的一般模式,您能帮我吗?
我不想做的事情:
- 完全摆脱上下文。在我的真实应用程序中,结构更复杂,整个应用程序的不同组件都需要这些信息,所以我相信我想坚持一个上下文
<Item>
避免从 dom中硬删除组件(使用{renderFirstBlock &&
),而是使用类似状态的东西isHidden
。在我的真实应用程序中,目前我无法更改。我的目标是跟踪data
所有现有的组件实例。
谢谢!
javascript - 我们应该在 React 功能组件的每个函数处理程序中使用 useCallback
假设我们有这样的组件
当我将onClick
处理程序作为箭头函数传递时,我eslint
会抛出警告:
简短的回答是因为每次都重新创建箭头函数,这会损害性能。这篇文章提出的一个解决方案是用一个空数组包裹在一个useCallback钩子中。当我改成这个时, eslint 警告真的消失了。
但是,也有另一种观点认为,由于 useCallback 的开销,过度使用useCallback 最终会降低性能。一个例子在这里:https ://kentcdodds.com/blog/usememo-and-usecallback
这让我真的很困惑?所以对于功能组件,在处理内联函数处理程序时,我应该只编写箭头函数(忽略 eslint)还是总是将它包装在 useCallback 中?
javascript - React:有或没有 useCallback 的优化回调
TL;博士
有的博客说不需要useCallback
每次给子组件传递回调时都使用钩子,有时每次都创建一个新函数会更好。因为useCallback
有时成本高于实际性能问题。虽然 React 警告说它可能会导致性能问题,但我们需要尽量避免它。
谁是对的,在这两种对立的主张之间取得平衡的方法是什么?
完整的问题
我最近一直在阅读很多关于 React hooks 的博客和教程,特别是关于useCallback
和useMemo
.
在 React 16(及其所有钩子)之前,当我使用类组件时,我一直使用“构造函数绑定”进行回调,因为箭头函数或“渲染中的绑定”如下所示:
被认为是“不良做法”。来自React 文档:
在渲染中使用 Function.prototype.bind 会在每次渲染组件时创建一个新函数,这可能会影响性能(见下文)。
在渲染中使用箭头函数会在每次渲染组件时创建一个新函数,这可能会破坏基于严格标识比较的优化。
所以,我的经验法则是不要将新函数传递给 props。
在 React 16 中,useCallback
钩子试图帮助我们做那件事。但是我看到很多类似的博客声称您不需要每次都使用钩子,因为有时成本高于实际问题,并且使用箭头函数在每次渲染时创建一个新函数很好。useCallback
useCallback
两种相反的说法都让我认为最好的选择应该是这样的(如果依赖项数组为空):
因为这种方式不使用“昂贵” useCallback
,并且不会每次都生成新功能。但是,实际上,当您有多个回调时,这段代码看起来并不那么好。
那么,这两种对立的主张之间的正确平衡是什么?如果每次创建一个新函数有时比使用更好useCallback
,为什么 React 在他们的文档中有一个警告?
(关于“双花括号”经验法则和useMemo
/useRef
钩子的相同问题)
reactjs - 解决 react-hooks/exhaustive-deps 的最佳方法
这是我的错误:“'setPartData' 函数使 useEffect Hook 的依赖项(在第 44 行)在每次渲染时都会发生变化。将其移动到 useEffect 回调中。或者,将 'setPartData' 定义包装到它自己的 useCallback() Hook 中。 eslint(react-hooks/exhaustive-deps)"
我应该如何最好地解决这个问题,因为我无法从数组中删除 url 和 setPartData 并禁用 eslint 规则。
我尝试了 useCallBack() 钩子,但我似乎在创建一个无限循环时错误地实现了它。任何帮助,将不胜感激。
reactjs - 将数据从子功能组件传递到父组件 - React/Typescript
我是 React 和 typescript 的新手。
我想做的事情:我有一个类组件,它呈现一个功能性的相机组件。当用户保存图像(来自相机组件)时,我想在父组件中使用该 base64 字符串。希望这是有道理的。
我的班级组件(父级)
我的相机组件:
我是我想从类组件访问的“imgSrc”。
-谢谢。
javascript - 在 React JS 的回调中使用自定义钩子
我有这个自定义钩子:
现在我想在我的代码中的某个地方使用它,如下所示:
现在问题是 eslint 警告说:
React Hook useCallback 缺少依赖项:'navigateHandler'。包括它或删除依赖数组
当我将依赖项navigateHandler
作为依赖项包含到useCallback
依赖项数组中时,eslint 说:
e 'navigateHandler' 函数使 useCallback Hook(在第 XXX 行)的依赖关系在每次渲染时发生变化。要解决此问题,请将“navigateHandler”定义包装到它自己的 useCallback() Hook 中
- 我不能改变
navigateHandler
功能。 - 我不确定另一个回调是否可以以最佳性能解决我的问题。
我该怎么办?
reactjs - 需要在 useCallback 中包装每个 useMemo 依赖项
我希望有一个人可以帮助我。我试图找到我的问题的答案,但我找不到,所以如果它在那里并且我找不到它,我提前道歉。
所以,我有一个昂贵的操作,它依赖于存储在 redux 存储中的 3 个对象。由于它很昂贵,我只想在这 3 个对象中的任何一个发生更改时才执行它。
为了避免使 useMemo 执行的函数过于复杂,我将其拆分为较小的函数,然后在需要时调用,如下所示:
现在,我不想将 processStoreObject1 列为 useMemo 的依赖项,计算值不依赖于它,计算值仅依赖于 3 存储对象。但是,如果我没有将该函数列为 useMemo 的依赖项,则会收到以下 lint 警告:
“React Hook useMemo 缺少依赖项:'processStoreObject1'。要么包含它,要么删除依赖项数组。eslint(react-hooks/exhaustive-deps)”
由于这个警告,我必须将函数包含在依赖数组中,并且因为函数是在组件内部声明的,类似于:
我必须将它包装在 useCallback 中,否则它会随着每次渲染而变化,并且 useMemo 一直在重新计算(这是错误的)。如果我不使用 useCallback 包装 processStoreObject1,我得到的警告是:
“'processStoreObject1' 函数使 useMemo Hook 的依赖关系(在 NNN 行)在每次渲染时都会发生变化。要解决这个问题,请将 'processStoreObject1' 定义包装到它自己的 useCallback() Hook.eslint(react-hooks/exhaustive-deps) "
我知道一个简单的解决方案是在组件外部定义 processStoreObject1 ,这样它就不会在每个渲染中创建,但我不喜欢这种方式,该函数只在组件内部使用,所以我想在那里定义。
总而言之,问题是,如何在不将依赖项添加到依赖项数组的情况下,在 useMemo 执行的函数中使用函数。我知道这是可行的,我看到了一些没有在依赖项数组中使用的函数示例。
如果有人可以帮助我,我将不胜感激。
谢谢 !
javascript - React Hook useEffect 缺少依赖
我正在使用 useEffect 钩子并且收到编译器错误提示React Hook useEffect has missing dependencies. Either include them or remove the dependency array react-hooks/exhaustive-deps
它对这两个功能都这么说。我想知道在这种情况下如何使用 useCallBack 钩子。我没有太多运气找到任何东西。任何摆脱这些编译器警告的帮助都将得到重视!