You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native FlatList数值增减操作卡顿问题求助

FlatList 点击按钮卡顿问题优化方案

核心问题分析

  1. React.memo 未生效:每次渲染时,renderItem 都会创建新的匿名回调函数,导致 MyItemComponent 的 props 频繁变化,无法跳过不必要的重渲染。
  2. 重复类型转换:每次增减操作都将 Остаток 从字符串转数字再转回字符串,增加了额外计算开销。
  3. 宽泛的 extraData 设置:使用整个 stopListData 作为 extraData,会触发 FlatList 对所有列表项的重新检查。
  4. 动态创建分隔组件: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,提问作者Евгений Руденко

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 04:42:04