React Native 鸿蒙跨平台开发:useCallback 和 useMemo
: T;接受一个泛型参数T,表示回调函数的类型callback:需要记忆化的回调函数deps:依赖项数组返回值:与回调函数类型相同的函数TuseMemo接受一个泛型参数T,表示返回值的类型factory:计算函数,返回值类型为Tdeps:依赖项数组返回值:类型为T的值。
一、核心知识点: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 中,每次组件重新渲染时,所有的函数都会被重新创建。这可能导致以下问题:
- 不必要的子组件重新渲染:如果将函数作为 props 传递给子组件,函数的重新创建会导致子组件不必要的重新渲染
- 性能浪费:频繁创建函数会占用内存和 CPU 资源
- 副作用问题:如果函数被用作 useEffect 的依赖项,函数的重新创建会导致副作用重复执行
3. useCallback 的基本语法
const memoizedCallback = useCallback(() => {
doSomething(a, b);
}, [a, b]);
参数说明:
- 回调函数:需要记忆化的函数
- 依赖项数组:只有当数组中的值发生变化时,才会重新创建函数
4. useCallback 的工作原理
当你调用 useCallback(callback, deps) 时,React 会:
- 首次渲染:创建回调函数并保存
- 依赖项检查:在后续渲染中,检查依赖项数组中的值是否发生变化
- 决定是否重新创建:
- 如果依赖项没有变化,返回之前创建的函数
- 如果依赖项发生变化,创建新的函数并保存
- 返回函数:返回(可能新的或旧的)回调函数
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 中,每次组件重新渲染时,所有的计算都会重新执行。这可能导致以下问题:
- 不必要的重复计算:复杂的计算(如排序、过滤、大数据处理)在每次渲染时都重新执行
- 性能浪费:频繁的复杂计算会占用大量 CPU 资源
- UI 卡顿:复杂的计算会阻塞主线程,导致 UI 卡顿
3. useMemo 的基本语法
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
参数说明:
- 计算函数:需要记忆化的计算函数
- 依赖项数组:只有当数组中的值发生变化时,才会重新计算
4. useMemo 的工作原理
当你调用 useMemo(compute, deps) 时,React 会:
- 首次渲染:执行计算函数并保存结果
- 依赖项检查:在后续渲染中,检查依赖项数组中的值是否发生变化
- 决定是否重新计算:
- 如果依赖项没有变化,返回之前计算的结果
- 如果依赖项发生变化,重新执行计算函数并保存结果
- 返回值:返回(可能新的或旧的)计算结果
5. useMemo 的类型定义
function useMemo<T>(factory: () => T, deps: DependencyList): T;
这个定义告诉我们:
useMemo接受一个泛型参数T,表示返回值的类型factory:计算函数,返回值类型为Tdeps:依赖项数组- 返回值:类型为
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
更多推荐



所有评论(0)