FlashList滚动复用组件时isActive状态未更新,求无性能损耗解决方案
解决方案
方案一:移除本地状态,直接使用传入的isSelected属性
问题根源在于FlashList组件复用时,useState的初始值仅在组件首次创建时生效,后续复用不会重新初始化。既然需求是完全同步isSelected的值,完全不需要维护本地的isActive状态,直接用传入的props值即可:
import {StyleSheet, View} from 'react-native'; import React from 'react'; import {FlashList} from '@shopify/flash-list'; interface CustomTestInterface { isSelected: boolean; } const CustomTest = ({isSelected}: CustomTestInterface) => { // 移除本地isActive状态,直接使用props的isSelected控制样式 return ( <View style={{ height: 80, width: '100%', backgroundColor: isSelected ? 'red' : 'gray', marginTop: 10, }} /> ); }; const Test = () => { const data = new Array(50).fill(false); data[1] = true; return ( <View style={{flex: 1, backgroundColor: 'green'}}> <FlashList data={data} estimatedItemSize={80} renderItem={({item}) => <CustomTest isSelected={item} />} /> </View> ); }; export default Test; const styles = StyleSheet.create({});
方案二:给列表项添加唯一key,避免组件复用(谨慎使用)
如果业务场景必须保留本地状态且不想用useEffect,可以给每个CustomTest组件添加唯一key,强制FlashList为每个项创建独立组件而不复用。注意此方法会降低列表滚动性能,仅适用于特殊场景:
// 在FlashList的renderItem中添加唯一key <FlashList data={data} estimatedItemSize={80} renderItem={({item, index}) => <CustomTest key={index} isSelected={item} />} />
方案三:用useMemo同步状态(无额外性能损耗)
如果必须保留本地状态,可使用useMemo替代useEffect同步isSelected,避免监听props变化带来的性能开销:
const CustomTest = ({isSelected}: CustomTestInterface) => { const [isActive, setIsActive] = useState<boolean>(isSelected); // 仅当isSelected与isActive不一致时更新状态 useMemo(() => { if (isActive !== isSelected) { setIsActive(isSelected); } }, [isSelected, isActive]); return ( <View style={{ height: 80, width: '100%', backgroundColor: isActive ? 'red' : 'gray', marginTop: 10, }} /> ); };
内容的提问来源于stack exchange,提问作者jalaliyev
相关产品推荐
相关产品推荐

