React中的useCallback跟useMeno的区别

本文对比了React中的useCallback与useMeno,前者用于优化函数依赖问题,后者减少不必要的计算。useCallback确保回调函数在依赖项不变时保持稳定,而useMeno则用于控制复杂的逻辑计算只在必要时更新。

前言

这里主要讲讲React中两个类似的hook,useCallback以及useMeno的区别,简单来讲就是

useMeno是内部返回的一个值
useCallback是内部返回的一个当前函数


一、example

1.1 useCallback

正常来说,当处理sideEffect的时候,useEffect的第二个参数会传一个dependence list,只有当list中地参数变化时候,这个effect才会被重新触发,比如

React.useEffect(() => {
  window.localStorage.setItem('count', count)
}, [count]) 

这里只有当count变化的时候,才会setItem(‘count’, count)到localstorage

这里的count是变量,如果是函数的话,就没那么简单了

const updateLocalStorage = () => window.localStorage.setItem('count', count)

React.useEffect(() => {
  updateLocalStorage()
}, [updateLocalStorage]) 

useEffect是定义在再component的函数体内的,一旦component被render,updateLocalStorage就会被重新initialised,所以dependency list中的updateLocalStorage肯定是会变化的,也就是useEffect每次都会因为component更新而重新执行

于是,useCallback就可以用上场了;updateLocalStorage 函数使用useCallback包裹,把count定义成它的dependency

const updateLocalStorage = React.useCallback(
  () => window.localStorage.setItem('count', count),
  [count], 
)
React.useEffect(() => {
  updateLocalStorage()
}, [updateLocalStorage])

1.2 useMeno

React可以让我们把所有的逻辑以及state management都放在一个function下面管理,但是这也带来一个limitation,那就是每次render所有的计算都需要执行一遍,不管组件内的计算是否有必要执行,比如

function Distance({x, y}) {
  const distance = calculateDistance(x, y)
  return (
    <div>
      The distance between {x} and {y} is {distance}.
    </div>
  )
}

如果这个组件的父组件re-render了,或者某些不相干的state触发了re-render,calculateDistance方法都会被执行,这就会带来performance瓶颈

这时候如果使用了useMemo

function Distance({x, y}) {
  const distance = React.useMemo(() => calculateDistance(x, y), [x, y])
  return (
    <div>
      The distance between {x} and {y} is {distance}.
    </div>
  )
}

这就是可以让calculateDistance的计算只会在x或者y变化的时候才触发,减少了无意义的计算


总结

useMeno跟useCallback作用类似,useMeno是内部返回的一个值,useCallback是内部返回的一个当前函数

<think>好的,我现在需要帮助用户了解React中的useCallback钩子的用法和示例。首先,我得回忆一下useCallback的基本概念和作用。记得useCallback是用来缓存函数实例的,避免在每次组件渲染时都创建新的函数,从而优化性能,特别是在依赖项不变的情况下。 用户可能需要知道为什么需要使用useCallback,以及它在什么情况下有用。通常,当将函数作为props传递给子组件,尤其是使用了React.memo的子组件时,使用useCallback可以防止不必要的重新渲染。此外,在依赖数组中的函数作为effect的依赖项时,使用useCallback可以避免effect的重复执行。 接下来,我需要组织回答的结构。首先应该解释useCallback的作用,然后给出基本语法,再举几个具体的例子。比如,一个简单的计数器例子,展示如何用useCallback缓存函数;另一个例子是传递回调给子组件,结合React.memo说明优化效果。可能还需要提到依赖项数组的重要性,以及错误使用可能导致的问题。 同时,用户提供的引用中有提到自定义钩子用于跨组件逻辑共享,可能可以提及useCallback在自定义钩子中的应用。比如在自定义钩子中返回被缓存的函数,确保不会因为函数引用变化而导致使用该钩子的组件不必要的更新。 还需要注意用户提到的格式要求,比如行内数学表达式用$...$,独立公式用$$...$$,不过在这个问题中可能用不上数学公式,但需要确保代码块正确使用反引号包裹,语言设置为javascript或jsx。 需要检查是否有相关的引用可以支持回答。查看用户提供的引用,引用[1]提到钩子是React团队解决许多问题的答案,使用它们有前提条件。引用[2]提到自定义钩子用于跨组件共享逻辑。这些可以用来支持useCallback的必要性和应用场景。 可能还需要考虑用户的实际应用场景,比如在列表渲染中,避免子组件因父组件函数引用变化而重复渲染,这时候useCallback就很有用。或者结合useEffect,当函数作为依赖项时,使用useCallback可以确保effect只在依赖变化时触发。 最后,生成相关问题,比如useCallbackuseMemo的区别,何时应该使用useCallback,或者如何处理依赖项数组中的变量变化等。这些问题可以帮助用户进一步深入学习。</think>### React useCallback 钩子的用法与示例 #### 1. 核心作用 `useCallback` 用于缓存函数实例,避免组件重新渲染时重复创建函数。这在以下场景中尤为重要: - 函数作为 **props 传递给子组件**,且子组件通过 `React.memo` 优化性能[^1] - 函数作为 **其他 Hook(如 useEffect)的依赖项**[^2] #### 2. 基础语法 ```javascript const memoizedCallback = useCallback( () => { // 函数逻辑 }, [dependency1, dependency2] // 依赖项数组 ); ``` #### 3. 典型使用场景 **场景一:优化子组件渲染** ```jsx // 父组件 const Parent = () => { const [count, setCount] = useState(0); // 使用 useCallback 缓存函数 const handleClick = useCallback(() => { setCount(c => c + 1); }, []); // 空依赖数组表示函数永不更新 return <Child onClick={handleClick} />; } // 子组件使用 React.memo 避免无效渲染 const Child = React.memo(({ onClick }) => { console.log('子组件渲染'); return <button onClick={onClick}>点击</button>; }); ``` **场景二:配合 useEffect 使用** ```jsx const fetchData = useCallback(async () => { const res = await fetch('/api/data'); return res.json(); }, []); // 依赖项为空时,函数引用保持不变 useEffect(() => { fetchData().then(data => console.log(data)); }, [fetchData]); // 安全地依赖缓存函数 ``` #### 4. 性能对比 | 方式 | 函数创建次数(渲染10次) | 子组件渲染次数 | |---------------|--------------------------|----------------| | 不使用 useCallback | 10次 | 10次 | | 使用 useCallback | 1次 | 1次 | #### 5. 注意事项 - **依赖项数组** 必须包含所有外部变量(如state/props) - 错误示例: ```javascript const [value] = useState(0); const badExample = useCallback(() => { console.log(value); // 缺少依赖项 value }, []); // 会导致永远输出初始值 ``` - 应与 `useMemo` 区分:`useMemo` 缓存计算结果,`useCallback` 缓存函数引用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值