一、核心知识点:useCallback 和 useMemo 完整核心用法

1. 用到的纯内置组件与 API

所有能力均为 RN 原生自带,全部从 react 核心包直接导入,无任何额外依赖、无任何第三方库,鸿蒙端无任何兼容问题,也是实现 useCallback 和 useMemo 的全部核心能力,零基础易理解、易复用,无任何冗余,所有 useCallback 和 useMemo 功能均基于以下组件/API 原生实现:

核心组件/API 作用说明 鸿蒙适配特性
useCallback React 原生钩子,优化回调函数,避免不必要的重新创建 ✅ 鸿蒙端回调优化正常,无兼容问题
useMemo React 原生钩子,优化计算结果,避免不必要的重复计算 ✅ 鸿蒙端计算优化正常,无兼容问题
useState React 原生钩子,管理组件状态 ✅ 鸿蒙端状态管理正常
useEffect React 原生钩子,处理副作用 ✅ 鸿蒙端副作用处理正常
View 核心容器组件,实现所有「性能测试容器、对比容器」,支持圆角、背景色、阴影 ✅ 鸿蒙端样式渲染无错位,宽高、圆角、背景色属性完美生效
Text 文本组件,显示性能信息和计算结果 ✅ 鸿蒙端文本渲染正常,支持多行文本
TextInput 输入框组件,实现用户输入和状态更新 ✅ 鸿蒙端输入框正常工作,支持键盘类型
TouchableOpacity 触摸反馈组件,实现交互和性能测试 ✅ 鸿蒙端触摸响应正常,交互流畅
StyleSheet 原生样式管理,编写鸿蒙端最优的 useCallback 和 useMemo 样式:性能显示样式、对比样式,无任何不兼容CSS属性 ✅ 贴合鸿蒙官方视觉设计规范,颜色、圆角、间距均为真机实测最优值
SafeAreaView 安全区域容器,适配刘海屏等异形屏 ✅ 鸿蒙端安全区域适配正常

二、深入理解 useCallback

1. useCallback 是什么?

useCallback 是 React 提供的一个 Hook,用于优化回调函数。它的主要作用是返回一个记忆化的回调函数,只有在依赖项发生变化时才会重新创建。

2. 为什么需要 useCallback?

在 React 中,每次组件重新渲染时,所有的函数都会被重新创建。这可能导致以下问题:

  1. 不必要的子组件重新渲染:如果将函数作为 props 传递给子组件,函数的重新创建会导致子组件不必要的重新渲染
  2. 性能浪费:频繁创建函数会占用内存和 CPU 资源
  3. 副作用问题:如果函数被用作 useEffect 的依赖项,函数的重新创建会导致副作用重复执行

3. useCallback 的基本语法

const memoizedCallback = useCallback(() => {
  doSomething(a, b);
}, [a, b]);

参数说明:

  • 回调函数:需要记忆化的函数
  • 依赖项数组:只有当数组中的值发生变化时,才会重新创建函数

4. useCallback 的工作原理

当你调用 useCallback(callback, deps) 时,React 会:

  1. 首次渲染:创建回调函数并保存
  2. 依赖项检查:在后续渲染中,检查依赖项数组中的值是否发生变化
  3. 决定是否重新创建
    • 如果依赖项没有变化,返回之前创建的函数
    • 如果依赖项发生变化,创建新的函数并保存
  4. 返回函数:返回(可能新的或旧的)回调函数

5. useCallback 的类型定义

function useCallback<T extends (...args: any[]) => any>(
  callback: T,
  deps: DependencyList
): T;

这个定义告诉我们:

  • useCallback 接受一个泛型参数 T,表示回调函数的类型
  • callback:需要记忆化的回调函数
  • deps:依赖项数组
  • 返回值:与回调函数类型相同的函数

6. useCallback 的使用场景

useCallback 适用于以下场景:

  • 传递给子组件的回调函数:避免子组件不必要的重新渲染
  • useEffect 的依赖项:避免副作用重复执行
  • 事件处理函数:优化事件处理性能
  • 自定义 Hook 的返回值:确保返回的函数引用稳定
  • 列表渲染的回调:避免列表项不必要的重新渲染

7. useCallback 的最佳实践

✅ 最佳实践 1:正确设置依赖项
// ❌ 不推荐:遗漏依赖项
const handleClick = useCallback(() => {
  console.log(count); // 使用了 count 但未在依赖项中
}, []);

// ✅ 推荐:包含所有使用的依赖项
const handleClick = useCallback(() => {
  console.log(count);
}, [count]);

原因

  • 确保回调函数总是使用最新的状态值
  • 避免闭包陷阱
  • ESLint 的 react-hooks/exhaustive-deps 规则会提醒你
✅ 最佳实践 2:避免过度使用
// ❌ 不推荐:不必要的 useCallback
const SimpleComponent = () => {
  const handleClick = useCallback(() => {
    console.log('clicked');
  }, []); // 这个函数很简单,不需要 useCallback
  
  return <TouchableOpacity onPress={handleClick}><Text>Click</Text></TouchableOpacity>;
};

// ✅ 推荐:直接定义函数
const SimpleComponent = () => {
  const handleClick = () => {
    console.log('clicked');
  };
  
  return <TouchableOpacity onPress={handleClick}><Text>Click</Text></TouchableOpacity>;
};

原因

  • useCallback 本身也有性能开销
  • 简单函数不需要优化
  • 只在确实需要时才使用
✅ 最佳实践 3:配合 React.memo 使用
// 子组件使用 React.memo 优化
const ChildComponent = React.memo(({ onClick }: { onClick: () => void }) => {
  console.log('ChildComponent 渲染');
  return <TouchableOpacity onPress={onClick}><Text>Click</Text></TouchableOpacity>;
});

// 父组件使用 useCallback 优化
const ParentComponent = () => {
  const [count, setCount] = useState(0);
  
  const handleClick = useCallback(() => {
    setCount(prev => prev + 1);
  }, []);
  
  return (
    <View>
      <Text>{count}</Text>
      <ChildComponent onClick={handleClick} />
    </View>
  );
};

原因

  • React.memo 会浅比较 props
  • useCallback 确保函数引用稳定
  • 避免子组件不必要的重新渲染

三、深入理解 useMemo

1. useMemo 是什么?

useMemo 是 React 提供的一个 Hook,用于优化计算结果。它的主要作用是返回一个记忆化的值,只有在依赖项发生变化时才会重新计算。

2. 为什么需要 useMemo?

在 React 中,每次组件重新渲染时,所有的计算都会重新执行。这可能导致以下问题:

  1. 不必要的重复计算:复杂的计算(如排序、过滤、大数据处理)在每次渲染时都重新执行
  2. 性能浪费:频繁的复杂计算会占用大量 CPU 资源
  3. UI 卡顿:复杂的计算会阻塞主线程,导致 UI 卡顿

3. useMemo 的基本语法

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

参数说明:

  • 计算函数:需要记忆化的计算函数
  • 依赖项数组:只有当数组中的值发生变化时,才会重新计算

4. useMemo 的工作原理

当你调用 useMemo(compute, deps) 时,React 会:

  1. 首次渲染:执行计算函数并保存结果
  2. 依赖项检查:在后续渲染中,检查依赖项数组中的值是否发生变化
  3. 决定是否重新计算
    • 如果依赖项没有变化,返回之前计算的结果
    • 如果依赖项发生变化,重新执行计算函数并保存结果
  4. 返回值:返回(可能新的或旧的)计算结果

5. useMemo 的类型定义

function useMemo<T>(factory: () => T, deps: DependencyList): T;

这个定义告诉我们:

  • useMemo 接受一个泛型参数 T,表示返回值的类型
  • factory:计算函数,返回值类型为 T
  • deps:依赖项数组
  • 返回值:类型为 T 的值

6. useMemo 的使用场景

useMemo 适用于以下场景:

  • 复杂计算:排序、过滤、大数据处理等
  • 对象创建:避免在每次渲染时创建新对象
  • 数组创建:避免在每次渲染时创建新数组
  • 派生状态:从现有状态计算出的新状态
  • 渲染优化:优化渲染性能,避免不必要的计算

7. useMemo 的最佳实践

✅ 最佳实践 1:正确设置依赖项
// ❌ 不推荐:遗漏依赖项
const filteredList = useMemo(() => {
  return items.filter(item => item.active); // 使用了 items 但未在依赖项中
}, []);

// ✅ 推荐:包含所有使用的依赖项
const filteredList = useMemo(() => {
  return items.filter(item => item.active);
}, [items]);

原因

  • 确保计算结果总是基于最新的数据
  • 避免闭包陷阱
  • ESLint 的 react-hooks/exhaustive-deps 规则会提醒你
✅ 最佳实践 2:避免过度使用
// ❌ 不推荐:不必要的 useMemo
const SimpleComponent = ({ name }: { name: string }) => {
  const greeting = useMemo(() => `Hello, ${name}!`, [name]); // 简单的字符串拼接不需要 useMemo
  
  return <Text>{greeting}</Text>;
};

// ✅ 推荐:直接计算
const SimpleComponent = ({ name }: { name: string }) => {
  const greeting = `Hello, ${name}!`;
  
  return <Text>{greeting}</Text>;
};

原因

  • useMemo 本身也有性能开销
  • 简单计算不需要优化
  • 只在计算确实昂贵时才使用
✅ 最佳实践 3:避免在 useMemo 中执行副作用
// ❌ 不推荐:在 useMemo 中执行副作用
const data = useMemo(() => {
  const result = expensiveCalculation(props.value);
  console.log('计算完成'); // 副作用
  localStorage.setItem('result', result); // 副作用
  return result;
}, [props.value]);

// ✅ 推荐:在 useEffect 中执行副作用
const data = useMemo(() => {
  return expensiveCalculation(props.value);
}, [props.value]);

useEffect(() => {
  console.log('计算完成');
  localStorage.setItem('result', data);
}, [data]);

原因

  • useMemo 应该是纯函数,不应该有副作用
  • 副作用应该在 useEffect 中处理
  • 避免不可预测的行为

四、useCallback 和 useMemo 的实战应用

1. 优化子组件渲染

import React, { useState, useCallback, memo } from 'react';
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';

// 子组件使用 React.memo 优化
const ChildComponent = memo(({ 
  count, 
  onIncrement, 
  onDecrement 
}: { 
  count: number; 
  onIncrement: () => void; 
  onDecrement: () => void; 
}) => {
  console.log('ChildComponent 渲染');
  
  return (
    <View style={styles.childContainer}>
      <Text style={styles.countText}>{count}</Text>
      <View style={styles.buttonRow}>
        <TouchableOpacity style={styles.childButton} onPress={onDecrement}>
          <Text style={styles.buttonText}>-</Text>
        </TouchableOpacity>
        <TouchableOpacity style={styles.childButton} onPress={onIncrement}>
          <Text style={styles.buttonText}>+</Text>
        </TouchableOpacity>
      </View>
    </View>
  );
});

// 父组件使用 useCallback 优化
const ParentComponent = () => {
  const [count, setCount] = useState(0);
  
  const handleIncrement = useCallback(() => {
    setCount(prev => prev + 1);
  }, []);
  
  const handleDecrement = useCallback(() => {
    setCount(prev => prev - 1);
  }, []);
  
  return (
    <View style={styles.container}>
      <Text style={styles.title}>父组件</Text>
      <ChildComponent 
        count={count} 
        onIncrement={handleIncrement} 
        onDecrement={handleDecrement} 
      />
    </View>
  );
};

2. 优化复杂计算

import React, { useState, useMemo } from 'react';
import { View, Text, StyleSheet } from 'react-native';

const ExpensiveCalculation = ({ 
  numbers, 
  filterValue 
}: { 
  numbers: number[]; 
  filterValue: number; 
}) => {
  // 使用 useMemo 优化计算
  const filteredNumbers = useMemo(() => {
    console.log('执行过滤计算');
    return numbers.filter(num => num > filterValue);
  }, [numbers, filterValue]);
  
  const sum = useMemo(() => {
    console.log('执行求和计算');
    return filteredNumbers.reduce((acc, num) => acc + num, 0);
  }, [filteredNumbers]);
  
  const average = useMemo(() => {
    console.log('执行平均值计算');
    return filteredNumbers.length > 0 ? sum / filteredNumbers.length : 0;
  }, [filteredNumbers, sum]);
  
  return (
    <View style={styles.container}>
      <Text style={styles.resultText}>过滤结果: {filteredNumbers.join(', ')}</Text>
      <Text style={styles.resultText}>总和: {sum}</Text>
      <Text style={styles.resultText}>平均值: {average.toFixed(2)}</Text>
    </View>
  );
};

3. 优化对象和数组创建

import React, { useState, useMemo } from 'react';
import { View, Text, StyleSheet } from 'react-native';

const ObjectArrayOptimization = ({ 
  data, 
  selectedId 
}: { 
  data: any[]; 
  selectedId: string; 
}) => {
  // 使用 useMemo 优化对象创建
  const selectedItem = useMemo(() => {
    return data.find(item => item.id === selectedId) || null;
  }, [data, selectedId]);
  
  // 使用 useMemo 优化数组创建
  const itemStyles = useMemo(() => {
    return data.map(item => ({
      backgroundColor: item.id === selectedId ? '#409EFF' : '#F5F7FA',
    }));
  }, [data, selectedId]);
  
  return (
    <View style={styles.container}>
      {data.map((item, index) => (
        <View 
          key={item.id} 
          style={[styles.item, itemStyles[index]]}
        >
          <Text style={styles.itemText}>{item.name}</Text>
        </View>
      ))}
    </View>
  );
};

五、实战完整版:企业级通用 useCallback 和 useMemo

import React, { useState, useCallback, useMemo, memo } from 'react';
import {
  View,
  Text,
  StyleSheet,
  TouchableOpacity,
  SafeAreaView,
  ScrollView,
  TextInput,
} from 'react-native';

// 优化后的子组件
const OptimizedChild = memo(({ 
  count, 
  name, 
  onIncrement,
  onDecrement 
}: { 
  count: number;
  name: string;
  onIncrement: () => void;
  onDecrement: () => void;
}) => {
  console.log(`OptimizedChild ${name} 渲染`);
  
  return (
    <View style={styles.childCard}>
      <Text style={styles.childName}>{name}</Text>
      <Text style={styles.childCount}>{count}</Text>
      <View style={styles.childButtonRow}>
        <TouchableOpacity 
          style={styles.childButton} 
          onPress={onDecrement}
        >
          <Text style={styles.childButtonText}>-</Text>
        </TouchableOpacity>
        <TouchableOpacity 
          style={styles.childButton} 
          onPress={onIncrement}
        >
          <Text style={styles.childButtonText}>+</Text>
        </TouchableOpacity>
      </View>
    </View>
  );
});

// 未优化的子组件
const UnoptimizedChild = ({ 
  count, 
  name, 
  onIncrement,
  onDecrement 
}: { 
  count: number;
  name: string;
  onIncrement: () => void;
  onDecrement: () => void;
}) => {
  console.log(`UnoptimizedChild ${name} 渲染`);
  
  return (
    <View style={styles.childCard}>
      <Text style={styles.childName}>{name}</Text>
      <Text style={styles.childCount}>{count}</Text>
      <View style={styles.childButtonRow}>
        <TouchableOpacity 
          style={styles.childButton} 
          onPress={onDecrement}
        >
          <Text style={styles.childButtonText}>-</Text>
        </TouchableOpacity>
        <TouchableOpacity 
          style={styles.childButton} 
          onPress={onIncrement}
        >
          <Text style={styles.childButtonText}>+</Text>
        </TouchableOpacity>
      </View>
    </View>
  );
};

// useCallback 示例
const UseCallbackExample = () => {
  const [count1, setCount1] = useState(0);
  const [count2, setCount2] = useState(0);
  
  // 使用 useCallback 优化回调函数
  const handleIncrement1 = useCallback(() => {
    setCount1(prev => prev + 1);
  }, []);
  
  const handleDecrement1 = useCallback(() => {
    setCount1(prev => prev - 1);
  }, []);
  
  const handleIncrement2 = useCallback(() => {
    setCount2(prev => prev + 1);
  }, []);
  
  const handleDecrement2 = useCallback(() => {
    setCount2(prev => prev - 1);
  }, []);
  
  // 未优化的回调函数
  const handleIncrement3 = useCallback(() => {
    setCount1(prev => prev + 1);
  }, []);
  
  const handleDecrement3 = useCallback(() => {
    setCount1(prev => prev - 1);
  }, []);
  
  console.log('UseCallbackExample 渲染');
  
  return (
    <View style={styles.card}>
      <View style={styles.cardHeader}>
        <Text style={styles.cardTitle}>useCallback 优化示例</Text>
      </View>
      <View style={styles.cardBody}>
        <Text style={styles.sectionTitle}>优化后的子组件</Text>
        <OptimizedChild 
          name="子组件1"
          count={count1}
          onIncrement={handleIncrement1}
          onDecrement={handleDecrement1}
        />
        <OptimizedChild 
          name="子组件2"
          count={count2}
          onIncrement={handleIncrement2}
          onDecrement={handleDecrement2}
        />
        
        <Text style={styles.sectionTitle}>未优化的子组件</Text>
        <UnoptimizedChild 
          name="子组件3"
          count={count1}
          onIncrement={handleIncrement3}
          onDecrement={handleDecrement3}
        />
      </View>
    </View>
  );
};

// useMemo 示例
const UseMemoExample = () => {
  const [numbers, setNumbers] = useState([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
  const [filterValue, setFilterValue] = useState(5);
  const [sortOrder, setSortOrder] = useState<'asc' | 'desc'>('asc');
  
  // 使用 useMemo 优化过滤计算
  const filteredNumbers = useMemo(() => {
    console.log('执行过滤计算');
    return numbers.filter(num => num > filterValue);
  }, [numbers, filterValue]);
  
  // 使用 useMemo 优化排序计算
  const sortedNumbers = useMemo(() => {
    console.log('执行排序计算');
    return [...filteredNumbers].sort((a, b) => {
      return sortOrder === 'asc' ? a - b : b - a;
    });
  }, [filteredNumbers, sortOrder]);
  
  // 使用 useMemo 优化统计计算
  const statistics = useMemo(() => {
    console.log('执行统计计算');
    const sum = sortedNumbers.reduce((acc, num) => acc + num, 0);
    const average = sortedNumbers.length > 0 ? sum / sortedNumbers.length : 0;
    const max = sortedNumbers.length > 0 ? Math.max(...sortedNumbers) : 0;
    const min = sortedNumbers.length > 0 ? Math.min(...sortedNumbers) : 0;
    
    return { sum, average, max, min };
  }, [sortedNumbers]);
  
  const handleFilterChange = useCallback((text: string) => {
    const value = parseInt(text) || 0;
    setFilterValue(value);
  }, []);
  
  const toggleSortOrder = useCallback(() => {
    setSortOrder(prev => prev === 'asc' ? 'desc' : 'asc');
  }, []);
  
  const addNumber = useCallback(() => {
    const newNumber = Math.floor(Math.random() * 100) + 1;
    setNumbers(prev => [...prev, newNumber]);
  }, []);
  
  return (
    <View style={styles.card}>
      <View style={styles.cardHeader}>
        <Text style={styles.cardTitle}>useMemo 优化示例</Text>
      </View>
      <View style={styles.cardBody}>
        <TextInput
          style={styles.input}
          placeholder="过滤值"
          value={filterValue.toString()}
          onChangeText={handleFilterChange}
          keyboardType="numeric"
        />
        
        <View style={styles.buttonRow}>
          <TouchableOpacity 
            style={styles.button}
            onPress={toggleSortOrder}
          >
            <Text style={styles.buttonText}>
              排序: {sortOrder === 'asc' ? '升序' : '降序'}
            </Text>
          </TouchableOpacity>
          <TouchableOpacity 
            style={styles.button}
            onPress={addNumber}
          >
            <Text style={styles.buttonText}>添加数字</Text>
          </TouchableOpacity>
        </View>
        
        <View style={styles.resultContainer}>
          <Text style={styles.resultLabel}>原始数组:</Text>
          <Text style={styles.resultValue}>{numbers.join(', ')}</Text>
        </View>
        
        <View style={styles.resultContainer}>
          <Text style={styles.resultLabel}>过滤后:</Text>
          <Text style={styles.resultValue}>{filteredNumbers.join(', ')}</Text>
        </View>
        
        <View style={styles.resultContainer}>
          <Text style={styles.resultLabel}>排序后:</Text>
          <Text style={styles.resultValue}>{sortedNumbers.join(', ')}</Text>
        </View>
        
        <View style={styles.statsContainer}>
          <View style={styles.statItem}>
            <Text style={styles.statLabel}>总和</Text>
            <Text style={styles.statValue}>{statistics.sum}</Text>
          </View>
          <View style={styles.statItem}>
            <Text style={styles.statLabel}>平均值</Text>
            <Text style={styles.statValue}>{statistics.average.toFixed(2)}</Text>
          </View>
          <View style={styles.statItem}>
            <Text style={styles.statLabel}>最大值</Text>
            <Text style={styles.statValue}>{statistics.max}</Text>
          </View>
          <View style={styles.statItem}>
            <Text style={styles.statLabel}>最小值</Text>
            <Text style={styles.statValue}>{statistics.min}</Text>
          </View>
        </View>
      </View>
    </View>
  );
};

// 性能对比示例
const PerformanceComparison = () => {
  const [data, setData] = useState<any[]>([]);
  const [selectedId, setSelectedId] = useState<string>('');
  
  // 使用 useMemo 优化对象创建
  const selectedItem = useMemo(() => {
    return data.find(item => item.id === selectedId) || null;
  }, [data, selectedId]);
  
  // 使用 useMemo 优化数组创建
  const itemStyles = useMemo(() => {
    return data.map(item => ({
      backgroundColor: item.id === selectedId ? '#409EFF' : '#F5F7FA',
    }));
  }, [data, selectedId]);
  
  // 使用 useCallback 优化事件处理
  const handleSelectItem = useCallback((id: string) => {
    setSelectedId(id);
  }, []);
  
  const handleAddItem = useCallback(() => {
    const newItem = {
      id: `item-${Date.now()}`,
      name: `项目 ${data.length + 1}`,
      value: Math.floor(Math.random() * 100),
    };
    setData(prev => [...prev, newItem]);
  }, [data.length]);
  
  const handleClearItems = useCallback(() => {
    setData([]);
    setSelectedId('');
  }, []);
  
  return (
    <View style={styles.card}>
      <View style={styles.cardHeader}>
        <Text style={styles.cardTitle}>性能对比示例</Text>
      </View>
      <View style={styles.cardBody}>
        <View style={styles.buttonRow}>
          <TouchableOpacity 
            style={styles.button}
            onPress={handleAddItem}
          >
            <Text style={styles.buttonText}>添加项目</Text>
          </TouchableOpacity>
          <TouchableOpacity 
            style={[styles.button, styles.resetButton]}
            onPress={handleClearItems}
          >
            <Text style={styles.buttonText}>清空</Text>
          </TouchableOpacity>
        </View>
        
        {selectedItem && (
          <View style={styles.selectedInfo}>
            <Text style={styles.selectedLabel}>选中项目:</Text>
            <Text style={styles.selectedName}>{selectedItem.name}</Text>
            <Text style={styles.selectedValue}>: {selectedItem.value}</Text>
          </View>
        )}
        
        {data.map((item, index) => (
          <TouchableOpacity
            key={item.id}
            style={[styles.listItem, itemStyles[index]]}
            onPress={() => handleSelectItem(item.id)}
          >
            <Text style={styles.listItemText}>{item.name}</Text>
            <Text style={styles.listItemValue}>{item.value}</Text>
          </TouchableOpacity>
        ))}
      </View>
    </View>
  );
};

// 主界面
const UseCallbackUseMemoScreen = () => {
  return (
    <SafeAreaView style={styles.container}>
      {/* 标题区域 */}
      <View style={styles.header}>
        <Text style={styles.pageTitle}>React Native for Harmony</Text>
        <Text style={styles.subtitle}>useCallback 和 useMemo</Text>
      </View>

      {/* 内容区域 */}
      <ScrollView style={styles.content}>
        <UseCallbackExample />
        <UseMemoExample />
        <PerformanceComparison />
        
        {/* 说明区域 */}
        <View style={styles.infoCard}>
          <Text style={styles.infoTitle}>💡 核心概念</Text>
          <Text style={styles.infoText}>• useCallback: 优化回调函数,避免不必要的重新创建</Text>
          <Text style={styles.infoText}>• useMemo: 优化计算结果,避免不必要的重复计算</Text>
          <Text style={styles.infoText}>• 依赖项数组: 控制何时重新创建或重新计算</Text>
          <Text style={styles.infoText}>• React.memo: 配合 useCallback 避免子组件重新渲染</Text>
          <Text style={styles.infoText}>• 性能优化: 只在必要时才使用,避免过度优化</Text>
          <Text style={styles.infoText}>• 鸿蒙端完美兼容,性能优秀</Text>
        </View>
      </ScrollView>
    </SafeAreaView>
  );
};

const App = () => {
  return <UseCallbackUseMemoScreen />;
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#F5F7FA',
  },

  // ======== 标题区域 ========
  header: {
    padding: 20,
    backgroundColor: '#FFFFFF',
    borderBottomWidth: 1,
    borderBottomColor: '#EBEEF5',
  },
  pageTitle: {
    fontSize: 24,
    fontWeight: '700',
    color: '#303133',
    textAlign: 'center',
    marginBottom: 8,
  },
  subtitle: {
    fontSize: 16,
    fontWeight: '500',
    color: '#909399',
    textAlign: 'center',
  },

  // ======== 内容区域 ========
  content: {
    flex: 1,
    padding: 16,
  },

  // ======== 卡片样式 ========
  card: {
    backgroundColor: '#FFFFFF',
    borderRadius: 12,
    marginBottom: 16,
    shadowColor: '#000000',
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.08,
    shadowRadius: 8,
    elevation: 4,
  },
  cardHeader: {
    padding: 16,
    borderBottomWidth: 1,
    borderBottomColor: '#EBEEF5',
  },
  cardTitle: {
    fontSize: 18,
    fontWeight: '600',
    color: '#303133',
  },
  cardBody: {
    padding: 16,
  },

  // ======== 渲染信息 ========
  renderInfo: {
    backgroundColor: '#F5F7FA',
    borderRadius: 8,
    padding: 12,
    marginBottom: 16,
  },
  renderInfoText: {
    fontSize: 14,
    color: '#606266',
    textAlign: 'center',
  },

  // ======== 子组件样式 ========
  sectionTitle: {
    fontSize: 16,
    fontWeight: '600',
    color: '#303133',
    marginTop: 16,
    marginBottom: 8,
  },
  childCard: {
    backgroundColor: '#F5F7FA',
    borderRadius: 8,
    padding: 12,
    marginBottom: 8,
  },
  childName: {
    fontSize: 14,
    color: '#909399',
    marginBottom: 4,
  },
  childCount: {
    fontSize: 24,
    fontWeight: '700',
    color: '#409EFF',
    marginBottom: 8,
  },
  childButtonRow: {
    flexDirection: 'row',
    justifyContent: 'center',
  },
  childButton: {
    backgroundColor: '#409EFF',
    paddingHorizontal: 16,
    paddingVertical: 8,
    borderRadius: 6,
    marginHorizontal: 4,
  },
  childButtonText: {
    color: '#FFFFFF',
    fontSize: 16,
    fontWeight: '600',
  },

  // ======== 输入框样式 ========
  input: {
    borderWidth: 1,
    borderColor: '#DCDFE6',
    borderRadius: 8,
    padding: 12,
    fontSize: 14,
    color: '#303133',
    marginBottom: 12,
  },

  // ======== 按钮样式 ========
  buttonRow: {
    flexDirection: 'row',
    marginBottom: 16,
  },
  button: {
    backgroundColor: '#409EFF',
    paddingHorizontal: 16,
    paddingVertical: 10,
    borderRadius: 6,
    marginRight: 8,
  },
  resetButton: {
    backgroundColor: '#F56C6C',
  },
  buttonText: {
    color: '#FFFFFF',
    fontSize: 14,
    fontWeight: '500',
  },

  // ======== 结果容器 ========
  resultContainer: {
    backgroundColor: '#F5F7FA',
    borderRadius: 8,
    padding: 12,
    marginBottom: 8,
  },
  resultLabel: {
    fontSize: 12,
    color: '#909399',
    marginBottom: 4,
  },
  resultValue: {
    fontSize: 12,
    color: '#303133',
    fontFamily: 'monospace',
  },

  // ======== 统计容器 ========
  statsContainer: {
    flexDirection: 'row',
    justifyContent: 'space-around',
    marginTop: 16,
    paddingTop: 16,
    borderTopWidth: 1,
    borderTopColor: '#EBEEF5',
  },
  statItem: {
    alignItems: 'center',
  },
  statLabel: {
    fontSize: 12,
    color: '#909399',
    marginBottom: 4,
  },
  statValue: {
    fontSize: 18,
    fontWeight: '600',
    color: '#409EFF',
  },

  // ======== 选中信息 ========
  selectedInfo: {
    backgroundColor: '#E6F7FF',
    borderRadius: 8,
    padding: 12,
    marginBottom: 16,
  },
  selectedLabel: {
    fontSize: 12,
    color: '#909399',
    marginBottom: 4,
  },
  selectedName: {
    fontSize: 16,
    fontWeight: '600',
    color: '#303133',
    marginBottom: 2,
  },
  selectedValue: {
    fontSize: 14,
    color: '#606266',
  },

  // ======== 列表项样式 ========
  listItem: {
    backgroundColor: '#FFFFFF',
    borderRadius: 8,
    padding: 12,
    marginBottom: 8,
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
  },
  listItemText: {
    fontSize: 14,
    color: '#303133',
  },
  listItemValue: {
    fontSize: 14,
    color: '#606266',
  },

  // ======== 信息卡片 ========
  infoCard: {
    backgroundColor: '#FFFFFF',
    borderRadius: 12,
    padding: 16,
    margin: 16,
    marginTop: 0,
    shadowColor: '#000000',
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.08,
    shadowRadius: 8,
    elevation: 4,
  },
  infoTitle: {
    fontSize: 16,
    fontWeight: '600',
    color: '#303133',
    marginBottom: 12,
  },
  infoText: {
    fontSize: 14,
    color: '#606266',
    lineHeight: 22,
    marginBottom: 6,
  },
});

export default App;

在这里插入图片描述
在这里插入图片描述

六、扩展用法:useCallback 和 useMemo 高频进阶优化

基于本次的核心 useCallback 和 useMemo 代码,结合RN的内置能力,可轻松实现鸿蒙端开发中所有高频的 useCallback 和 useMemo 进阶需求,全部为纯原生API实现,无需引入任何第三方库,零基础只需在本次代码基础上做简单修改即可实现,实用性拉满,全部真机实测通过,无任何兼容问题,满足企业级高阶需求:

✔️ 扩展1:useRef 解决闭包陷阱

适配「闭包问题」的场景,支持 useRef 解决闭包,无需改动核心逻辑,一行代码实现,鸿蒙端完美兼容:

const Timer = () => {
  const [count, setCount] = useState(0);
  const countRef = useRef(count);
  
  // 更新 ref 的值
  useEffect(() => {
    countRef.current = count;
  }, [count]);
  
  // 使用 ref 避免闭包陷阱
  useEffect(() => {
    const interval = setInterval(() => {
      console.log('Current count:', countRef.current);
    }, 1000);
    
    return () => clearInterval(interval);
  }, []); // 空依赖数组,只在挂载时执行一次
  
  return <Text>{count}</Text>;
};

✔️ 扩展2:useMemo 优化复杂对象

适配「复杂对象」的场景,支持 useMemo 优化复杂对象,无需改动核心逻辑,一行代码实现,鸿蒙端完美兼容:

const ComplexObject = ({ data, config }: { data: any[]; config: any }) => {
  const processedData = useMemo(() => {
    // 复杂的数据处理
    return data.map(item => ({
      ...item,
      processed: true,
      timestamp: Date.now(),
      metadata: {
        ...config,
        id: item.id,
      },
    }));
  }, [data, config]);
  
  const styles = useMemo(() => ({
    container: {
      padding: config.padding || 16,
      backgroundColor: config.backgroundColor || '#FFFFFF',
    },
    item: {
      margin: config.margin || 8,
      borderRadius: config.borderRadius || 8,
    },
  }), [config]);
  
  return (
    <View style={styles.container}>
      {processedData.map(item => (
        <View key={item.id} style={styles.item}>
          <Text>{item.name}</Text>
        </View>
      ))}
    </View>
  );
};

✔️ 扩展3:useCallback 优化事件处理

适配「事件处理」的场景,支持 useCallback 优化事件,无需改动核心逻辑,一行代码实现,鸿蒙端完美兼容:

const EventHandling = () => {
  const [events, setEvents] = useState<string[]>([]);
  
  // 使用 useCallback 优化事件处理函数
  const handleClick = useCallback((id: string) => {
    setEvents(prev => [...prev, `Clicked: ${id}`]);
  }, []);
  
  const handleDoubleClick = useCallback((id: string) => {
    setEvents(prev => [...prev, `DoubleClicked: ${id}`]);
  }, []);
  
  const handleLongPress = useCallback((id: string) => {
    setEvents(prev => [...prev, `LongPressed: ${id}`]);
  }, []);
  
  const clearEvents = useCallback(() => {
    setEvents([]);
  }, []);
  
  return (
    <View>
      <TouchableOpacity onPress={() => handleClick('button1')}>
        <Text>Click</Text>
      </TouchableOpacity>
      <TouchableOpacity onLongPress={() => handleLongPress('button2')}>
        <Text>Long Press</Text>
      </TouchableOpacity>
      {events.map((event, index) => (
        <Text key={index}>{event}</Text>
      ))}
      <TouchableOpacity onPress={clearEvents}>
        <Text>Clear</Text>
      </TouchableOpacity>
    </View>
  );
};

✔️ 扩展4:useMemo 优化列表渲染

适配「列表渲染」的场景,支持 useMemo 优化列表,无需改动核心逻辑,一行代码实现,鸿蒙端完美兼容:

const ListRendering = ({ items, filterText, sortBy }: { items: any[]; filterText: string; sortBy: string }) => {
  const filteredAndSortedItems = useMemo(() => {
    let result = items;
    
    // 过滤
    if (filterText) {
      result = result.filter(item => 
        item.name.toLowerCase().includes(filterText.toLowerCase())
      );
    }
    
    // 排序
    if (sortBy) {
      result = [...result].sort((a, b) => {
        if (a[sortBy] < b[sortBy]) return -1;
        if (a[sortBy] > b[sortBy]) return 1;
        return 0;
      });
    }
    
    return result;
  }, [items, filterText, sortBy]);
  
  return (
    <FlatList
      data={filteredAndSortedItems}
      keyExtractor={item => item.id}
      renderItem={({ item }) => (
        <Text>{item.name}</Text>
      )}
    />
  );
};

✔️ 扩展5:useCallback 和 useMemo 配合使用

适配「复杂场景」的场景,支持配合使用,无需改动核心逻辑,一行代码实现,鸿蒙端完美兼容:

const ComplexScenario = ({ data, config }: { data: any[]; config: any }) => {
  const [selectedIds, setSelectedIds] = useState<Set<string>>(new Set());
  
  // 使用 useMemo 优化数据处理
  const processedData = useMemo(() => {
    return data.map(item => ({
      ...item,
      isSelected: selectedIds.has(item.id),
    }));
  }, [data, selectedIds]);
  
  // 使用 useMemo 优化统计计算
  const statistics = useMemo(() => {
    const total = processedData.length;
    const selected = processedData.filter(item => item.isSelected).length;
    const unselected = total - selected;
    
    return { total, selected, unselected };
  }, [processedData]);
  
  // 使用 useCallback 优化选择操作
  const toggleSelection = useCallback((id: string) => {
    setSelectedIds(prev => {
      const newSet = new Set(prev);
      if (newSet.has(id)) {
        newSet.delete(id);
      } else {
        newSet.add(id);
      }
      return newSet;
    });
  }, []);
  
  const selectAll = useCallback(() => {
    setSelectedIds(new Set(processedData.map(item => item.id)));
  }, [processedData]);
  
  const clearSelection = useCallback(() => {
    setSelectedIds(new Set());
  }, []);
  
  // 使用 useMemo 优化操作按钮
  const actions = useMemo(() => [
    { label: '全选', handler: selectAll },
    { label: '清空', handler: clearSelection },
  ], [selectAll, clearSelection]);
  
  return (
    <View>
      <View style={styles.stats}>
        <Text>总计: {statistics.total}</Text>
        <Text>已选: {statistics.selected}</Text>
        <Text>未选: {statistics.unselected}</Text>
      </View>
      {processedData.map(item => (
        <TouchableOpacity
          key={item.id}
          onPress={() => toggleSelection(item.id)}
          style={[styles.item, item.isSelected && styles.itemSelected]}
        >
          <Text>{item.name}</Text>
        </TouchableOpacity>
      ))}
      <View style={styles.actions}>
        {actions.map((action, index) => (
          <TouchableOpacity
            key={index}
            onPress={action.handler}
            style={styles.actionButton}
          >
            <Text>{action.label}</Text>
          </TouchableOpacity>
        ))}
      </View>
    </View>
  );
};

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐