React Native FlatList数值增减操作卡顿问题求助
FlatList 点击按钮卡顿问题优化方案
核心问题分析
- React.memo 未生效:每次渲染时,
renderItem都会创建新的匿名回调函数,导致MyItemComponent的 props 频繁变化,无法跳过不必要的重渲染。 - 重复类型转换:每次增减操作都将
Остаток从字符串转数字再转回字符串,增加了额外计算开销。 - 宽泛的 extraData 设置:使用整个
stopListData作为extraData,会触发 FlatList 对所有列表项的重新检查。 - 动态创建分隔组件:
ItemSeparatorComponent每次渲染都生成新的组件实例,造成不必要的性能损耗。
具体优化步骤
1. 用 useCallback 包裹状态更新函数,使用函数式更新
使用函数式更新获取最新状态,避免依赖 stopListData,保证函数引用稳定:
const handleIncrement = useCallback((itemId) => { setStopListData(prevData => prevData.map(entry => entry.id === itemId ? { ...entry, Остаток: entry.Остаток + 1 } : entry ) ); }, []); const handleDecrement = useCallback((itemId) => { setStopListData(prevData => prevData.map(entry => entry.id === itemId && entry.Остаток > 0 ? { ...entry, Остаток: entry.Остаток - 1 } : entry ) ); }, []);
2. 优化列表项组件的回调传递
修改 MyItemComponent,直接接收稳定的状态更新函数,避免在 renderItem 中创建匿名函数:
const MyItemComponent = React.memo(({ item, handleIncrement, handleDecrement }) => { return ( <View style={styles.itemContainer}> <Text style={styles.itemText}>{item.Товар}</Text> <View style={{ flexDirection: 'row', alignItems: 'center' }}> <TouchableOpacity onPress={() => handleDecrement(item.id)} style={styles.button}> <Text style={styles.buttonText}>—</Text> </TouchableOpacity> <Text style={[styles.counterText, { minWidth: 50, textAlign: 'center', color: '#FF9A00', fontWeight: 'bold' }]}>{item.Остаток}</Text> <TouchableOpacity onPress={() => handleIncrement(item.id)} style={styles.button}> <Text style={styles.buttonText}>+</Text> </TouchableOpacity> </View> </View> ); }); // 用 useCallback 包裹 renderItem,保证引用稳定 const renderItem = useCallback(({ item }) => ( <MyItemComponent item={item} handleIncrement={handleIncrement} handleDecrement={handleDecrement} /> ), [handleIncrement, handleDecrement]);
3. 统一存储数字类型的 Остаток
在数据获取阶段将 Остаток 转换为数字,避免每次操作重复转换:
const fetchData = async () => { const data = await getStopList(); const formattedData = data.Данные.map(item => ({ ...item, Остаток: parseInt(item.Остаток, 10) // 转换为数字并指定基数,避免解析错误 })); setStopListData(formattedData); };
4. 优化 FlatList 配置
- 移除冗余的
extraData:FlatList 会自动跟踪data的变化,结合 React.memo 即可实现精准渲染。 - 用 useMemo 缓存分隔组件,避免重复创建:
const Separator = useMemo(() => () => <View style={styles.separator} />, []); // FlatList 中使用缓存后的分隔组件 <FlatList data={stopListData} renderItem={renderItem} keyExtractor={keyExtractor} initialNumToRender={15} onRefresh={onRefresh} refreshing={isFetching} ItemSeparatorComponent={Separator} />
内容的提问来源于stack exchange,提问作者Евгений Руденко
相关产品推荐
相关产品推荐

