react 如何使用useCallback 避免全量更新?
在子组件的事件中使用useCallback
父组件 list.map 创建了子组件, 子组件触发事件导致 父组件的 list 发生变更, 于是组件全部发生了变化
这个过程中只有其中一个子组件发生了改变,所以我使用了 memo 包裹了一下
但是 传递的事件函数会重复创建,导致子组件全量更新
我应该如何使用useCallback 来实现顶点更新?
<SingleCircle fill="#fff" name={name} x={x} y={y} radius={4 / scale} onDragEnd={() => onDrop(name)} onDragMove={(e: TKDragEvent) => onDragMove(e, index)} onMouseOver={() => dispatch(setSelectPointKey(name))} // 注释这样写会报错 // onDragEnd={useCallback(() => onDrop(name), [])} // onDragMove={useCallback((e: TKDragEvent) => onDragMove(e, index), [index])} // onMouseOver={useCallback(() => dispatch(setSelectPointKey(name)), [])}/>
把 useCallback
提到外面去就好了,报错是因为这样写在 map
循环里面
当然还可以使用其他方案
ahooks
里面的 useMemoizedFn
,是之前 React
官方 useEvent
提案的实现,函数引用始终不会变,并且不会产生过期闭包,无需依赖项要使用 useCallback
来避免不必要的重新渲染,你需要确保回调函数在每次渲染时都保持不变。在你的例子中,你可以使用 useCallback
来创建这些回调函数,并将它们作为 onDragEnd
、onDragMove
和 onMouseOver
的属性。
首先,你需要创建一个状态变量来存储 onDrop
、onDragMove
和 setSelectPointKey
函数的引用。然后,在函数体内部,使用 useCallback
钩子来创建一个回调函数,并将其存储在相应的状态变量中。
下面是一个示例代码:
import React, { useState, useCallback } from 'react';function ParentComponent() { const [list, setList] = useState([/* 初始列表 */]); const [selectedPointKey, setSelectedPointKey] = useState(null); const onDrop = (name) => { // 处理 onDrop 逻辑 }; const onDragMove = (e, index) => { // 处理 onDragMove 逻辑 }; const setSelectPointKey = (name) => { // 处理 setSelectPointKey 逻辑 }; const onDragEndCallback = useCallback(() => onDrop, []); // 创建 onDrop 回调函数 const onDragMoveCallback = useCallback((e, index) => onDragMove(e, index), [index]); // 创建 onDragMove 回调函数,并依赖 index 防止重新渲染 const setSelectPointKeyCallback = useCallback(() => setSelectPointKey, []); // 创建 setSelectPointKey 回调函数 return ( <div> {list.map((item, index) => ( <SingleCircle fill="#fff" name={item.name} x={item.x} y={item.y} radius={4 / item.scale} onDragEnd={onDragEndCallback} // 使用创建的回调函数作为 onDragEnd 属性 onDragMove={(e: TKDragEvent) => onDragMoveCallback(e, index)} // 使用创建的回调函数作为 onDragMove 属性,并传递 index 作为参数 onMouseOver={() => setSelectedPointKey(item.name)} // 根据你的需求修改 onMouseOver 处理函数 /> ))} </div> );}
这样,只有当 index
值改变时,onDragMove
的回调函数才会改变,从而触发组件的重新渲染。其他情况下,回调函数保持不变,因此不会触发不必要的重新渲染。
问题内容: 我们都知道全局变量只是最佳实践。但是在有些情况下,没有它们很难编写代码。您使用什么技术来避免使用全局变量? 例如,在以下情况下,您将如何不使用全局变量? JavaScript代码: 相关标记: 此代码来自具有多个的网络表单。它一次上传一个文件,以防止大量请求。它通过POST到iframe来完成此操作,等待响应触发iframeonload,然后触发下一个提交。 您不必专门回答此示例,我只
现在遇到一个项目,uniapp开发的微信小程序,之前的所有页面都没有使用scope将css样式私有化,导致css属性全局污染了,现在要开发后续的功能,如何在后续的开发中避免之前css的样式污染? 之前开发的内容不能使用scope将css私有化,因为一旦私有化可能会对某些页面造成影响,现在的情况就是之前的内容不能动,在此基础上开发。 目前想到的办法是在后续开发的功能中,所有的css类名名全部使用当前
我最近开始将样式化组件与React一起使用,我不确定我是否正确地处理了一个不断重复出现的特定情况。 假设我有一个非常简单的组件,比如,它只需要非常多的样式和一些给定的内容。我现在要处理的事情如下: 我发现首先定义基本组件,如,只针对样式,然后再定义另一个组件,它接受道具并使用该样式组件。 有没有更短的方法只在一个组件中完成这两个任务?我希望能有一些像... ...但那似乎不起作用。
我一直在思考jvm安全的工作方式。原则是,jvm始终信任并运行任何本地代码。因此,从概念上讲,如果您的代码没有显式或隐式调用<code>checkpermission(permission)</code>,这意味着它永远不会失败任何安全验证。当然,所有这些验证调用通常都是在JavaAPI类中完成的,因此我们不需要为内置权限调用它们。 现在,只要您使用内置类(如<code>FileOutputStr
我有一个带有jsonb列的PostgreSQL表,其中包含一个字符串数组,这些字符串是标记值,如下所示:。我有一个自定义绑定,用于将JSON与jackson JSONode进行转换。 自定义绑定定义如下:https://gist.github.com/helgeg/0C0B14228F75E91B7542BD6979A05B49 用基本的find读取记录,然后我提取JSON列,如下所示: 这是使用
Facebook React鼓励您将可变()和不可变()状态分开: 尽量让您的组件尽可能多的无状态。通过这样做,您可以将状态隔离到最符合逻辑的位置,并最大限度地减少冗余,从而更容易对应用程序进行推理。 当状态改变时,您应该调用来触发虚拟DOM diff,只有在需要时才会导致真正的DOM更新。 有一种方法可以通过调用手动触发DOM更新,但不鼓励: 通常情况下,您应该尽量避免使用,并且只从和中的读取。