React Native 中的 useCallback

一个简单的比喻:点菜和厨师

想象一下,你是一个顾客(组件),你在一个餐厅里点菜。

没有 useCallback 的情况(普通做法):

  • 你每次喊服务员(子组件)过来,哪怕只是问一句"我的菜好了吗?",你都会重新写一张全新的、一模一样的菜单交给他。
  • 服务员(子组件)很困惑:"这张新菜单和上一张完全一样啊?为什么又要给我一份?"
    虽然他可能还是会去后厨问一下,但这个"重新写菜单"的动作是多余的,浪费了纸张和精力。

使用 useCallback 的情况(聪明做法):

  • 你第一次点菜时,写好了菜单(创建了函数)。

  • 你告诉服务员:"这是我的菜单,只要我点的菜不变(依赖项不变),你就一直用这张旧菜单,不用我每次都重写。"

  • 这样,只有当你想加菜或退菜(依赖项改变)时,你才会写一张新菜单给他。否则,每次都递给他同一张旧菜单。

服务员(子组件)拿到旧菜单,一看:"哦,这张菜单和上次一模一样,内容根本没变,我就不用再跑去后厨问厨师了,直接告诉你'还没好'就行了。" 这样就节省了不必要的沟通成本。

在代码里是什么意思?

在 React Native 中,这个"服务员"通常就是你的子组件,特别是用 React.memo 包装过的、被优化过的子组件。

  • 函数(菜单): 就是你定义在组件内部的函数,比如 handlePress, onSubmit
  • 依赖项(点的菜): 就是函数内部使用到的、来自组件外部的变量,比如 state, props

为什么要用 useCallback

主要目的是性能优化。通过避免在每次渲染时都创建新的函数,可以让依赖于此函数的子组件避免不必要的重新渲染。

语法超级简单

javascript 复制代码
import { useCallback } from 'react';

const MyComponent = () => {
  const [count, setCount] = useState(0);

  // 没有 useCallback - 每次渲染都创建新函数
  // const handlePress = () => {
  //   console.log('Pressed!', count);
  // };

  // 使用 useCallback - 只有当 count 改变时,才会创建新函数
  const handlePress = useCallback(() => {
    console.log('Pressed!', count);
  }, [count]); // <-- 依赖项数组:count 变了,函数才更新

  return (
    <View>
      <Text>Count: {count}</Text>
      {/* 这个ChildComponent如果用了React.memo,就能从useCallback中受益 */}
      <ChildComponent onPress={handlePress} />
    </View>
  );
};

给小白的关键总结

  1. 是什么: useCallback 是一个"记忆函数"的工具。它能把一个函数"缓存"起来。

  2. 为什么用: 为了防止因为父组件重新渲染,导致传给子组件的函数每次都变成新的,从而触发子组件不必要的渲染。主要是为了性能优化。

  3. 什么时候用:

    • 当你把一个函数作为 prop 传递给一个被 React.memo 包装的子组件时。

    • 当你把一个函数作为依赖项传给其他 Hook(比如 useEffect)时。

  4. 怎么用: 用 useCallback 把你的函数包起来,并在第二个参数里告诉它,这个函数依赖了哪些变量。

最后提醒 : 不要滥用!不是每个函数都需要 useCallback。只有当它真的能解决性能问题时才使用。对于简单的组件,用了反而可能增加复杂度,得不偿失。先写没有它的代码,遇到性能问题再考虑它。

相关推荐
Larcher2 分钟前
从回调地狱到优雅异步:Node.js 文件操作进化史
javascript·后端·架构
熊猫钓鱼>_>28 分钟前
Electron:当 Web 技术统治桌面
大数据·前端·javascript·人工智能·架构·electron·agent
飞天狗1 小时前
长列表滚动卡顿怎么破:虚拟列表选型 + react-virtuoso 实战调优指南
react.js·性能优化
江华森1 小时前
Python 实现高德地图找房(三):地图可视化与高德 JS API
开发语言·javascript·python
谭光志1 小时前
AI 是怎么操作浏览器的——browser use 实现原理
前端·javascript·ai编程
用户3074596982071 小时前
GatewayWorker 从零到一完整指南
javascript·php
铁皮饭盒1 小时前
Bun.redis真正的强项
javascript
用户938515635072 小时前
Node.js 路径与文件系统:从基础到异步进化之路
javascript·后端·面试
Cobyte2 小时前
23.Vue Vapor 组件 attrs 的实现
前端·javascript·vue.js
触底反弹3 小时前
🚀 Node.js path 和 fs 模块,从回调地狱到 async/await 的进化之路!
javascript·后端·node.js