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。只有当它真的能解决性能问题时才使用。对于简单的组件,用了反而可能增加复杂度,得不偿失。先写没有它的代码,遇到性能问题再考虑它。

相关推荐
专注前端30年12 分钟前
【JavaScript】reduce 方法的详解与实战
开发语言·前端·javascript
专注前端30年1 小时前
2025 最新 Vue2/Vue3 高频面试题(10月最新版)
前端·javascript·vue.js·面试
Highcharts.js2 小时前
选择合适的组合:如何打造数据可视化的“黄金组合”
javascript·信息可视化·highcharts·交互式图表开发
angelQ2 小时前
Vue 3 中 ref 获取 scrollHeight 属性为 undefined 问题定位
前端·javascript
我的div丢了肿么办3 小时前
js函数声明和函数表达式的理解
前端·javascript·vue.js
AAA阿giao3 小时前
JavaScript 对象字面量与代理模式:用“胡巴送花”讲透面向对象与设计思想
javascript
高台树色3 小时前
终于记住Javascript垃圾回收机制
javascript
举个栗子dhy3 小时前
第二章、全局配置项目主题色(主题切换+跟随系统)
前端·javascript·react.js
sorryhc3 小时前
开源的SSR框架都是怎么实现的?
前端·javascript·架构
fox_3 小时前
别再混淆 call/apply/bind 了!一篇讲透用法、场景与手写逻辑(二)
前端·javascript