React Native列表组件选中交互卡顿的优化方案咨询
我来帮你梳理下这个组件的性能瓶颈,然后给出几个具体的优化方案,应该能明显提升点击响应速度:
1. 把数组状态改成Set,优化查找性能
你现在用state.StylesRecherches.includes(item.value)判断是否选中,这是**O(n)**的遍历操作——每判断一次就要扫一遍整个数组,当选中的项变多的时候,这个操作会越来越慢。
换成Set的话,查找操作是**O(1)**的,瞬间就能完成。咱们来修改Reducer和组件里的判断逻辑:
修改Reducer代码:
case "ADD_STYLES_RECHERCHES": return { ...state, // 把原Set转成新Set,添加新值 StylesRecherches: new Set([...state.StylesRecherches, action.payload.value]), }; case "DELETE_STYLES_RECHERCHES" : const newSelectedSet = new Set(state.StylesRecherches); newSelectedSet.delete(action.payload.value); return { ...state, StylesRecherches: newSelectedSet, };
组件里修改判断逻辑:
把所有state.StylesRecherches.includes(item.value)替换成state.StylesRecherches.has(item.value)即可。
2. 抽离并缓存列表项组件,减少不必要重渲染
你现在在renderCustomItem里直接写了Pressable和View,每次父组件渲染时,这个函数都会重新创建,导致所有列表项都跟着重渲染——哪怕只有一个项的状态变化,其他项也会重新渲染一遍。
咱们把列表项抽成单独的React.memo组件,只有当props变化时才会重渲染:
// 抽离成单独的memo组件 const ListItem = React.memo(({ item, isSelected, onToggle }) => { return ( <Pressable onPress={() => onToggle(item)}> <View style={{ flex: 1, flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', padding: 10, borderBottomWidth: 1, borderBottomColor: '#ccc', backgroundColor: isSelected ? '#00cc00' : '#f2f2f2' }}> <Text style={styles.listItemLabel}>{item.value}</Text> </View> </Pressable> ); });
然后在renderCustomItem里调用这个组件:
renderCustomItem={(item) => ( <View key={item.key}> <ListItem item={item} isSelected={state.StylesRecherches.has(item.value)} onToggle={onToggleItem} /> </View> )}
3. 缓存点击回调函数,避免不必要的props变化
咱们再用useCallback把点击回调函数缓存起来,这样只有当选中状态变化时,这个函数才会重新创建,避免ListItem因为回调函数变化而重渲染:
const onToggleItem = React.useCallback((item) => { if (state.StylesRecherches.has(item.value)) { removeStylesRecherches(item); } else { addStylesRecherches(item); } }, [state.StylesRecherches]);
4. 给组件本身加上React.memo,防止无意义重渲染
最后,把整个ListStyleSpectacle组件用React.memo包裹,这样当navigation等props没有变化时,哪怕Context里的其他状态变化,这个组件也不会重渲染:
export default React.memo(function ListStyleSpectacle({ navigation}) { // 原组件内容不变 });
额外小优化:去掉不必要的日志
把useEffect里的console.log(state.StylesRecherches)去掉(或者只在开发环境保留),日志输出虽然看起来不影响,但频繁的输出也会占用一点性能。
这些优化组合起来,应该能解决你遇到的响应迟缓问题——核心是把O(n)的查找变成O(1),同时减少不必要的组件重渲染,让点击操作的反馈更即时。
内容的提问来源于stack exchange,提问作者ggg

