React Native中FlatList内设置useRef值遇未定义及useCallback报错问题
解决React Native FlatList中onViewableItemsChanged设置ref的问题
问题原因
你遇到的currentId.current始终为undefined,是因为用useRef包裹的回调函数形成闭包,捕获的是组件初始渲染时的上下文;改用useCallback后报错,则是FlatList在回调更新后,内部视图可观察性配置未正确同步导致的。
解决方法一:使用viewabilityConfigCallbackPairs替代直接传onViewableItemsChanged
React Native FlatList提供的viewabilityConfigCallbackPairs属性,专门用于处理动态变化的onViewableItemsChanged回调,既能避免重渲染报错,又能正常访问最新的ref引用。
代码示例:
const MyComponent = (): JSX.Element => { const currentId = useRef(''); // 定义视图可见性判定规则,可根据需求调整阈值 const viewabilityConfig = useRef({ itemVisiblePercentThreshold: 50, }).current; // 用useCallback创建回调,依赖为空(访问ref的current无需加入依赖) const onViewableItemsChanged = useCallback(({ viewableItems }) => { if (viewableItems.length > 0) { // 这里以第一个可见item的id为例,可根据业务逻辑调整 currentId.current = viewableItems[0].item.id; } }, []); // 配置回调与可见性规则的配对 const viewabilityConfigCallbackPairs = useRef([ { viewabilityConfig, onViewableItemsChanged }, ]).current; return ( <FlatList // 其他必填props:data、renderItem等 keyExtractor={(item) => item.id} viewabilityConfigCallbackPairs={viewabilityConfigCallbackPairs} /> ); };
解决方法二:直接用ref持有回调,访问可变的ref引用
如果坚持用useRef包裹回调,可直接在回调内访问currentId的可变引用(ref的current不受闭包捕获限制):
const MyComponent = (): JSX.Element => { const currentId = useRef(''); const onViewableItemsChangedRef = useRef(({ viewableItems }) => { if (viewableItems.length > 0) { currentId.current = viewableItems[0].item.id; } }); return ( <FlatList // 其他必填props:data、renderItem等 keyExtractor={(item) => item.id} onViewableItemsChanged={onViewableItemsChangedRef.current} /> ); };
注:若之前出现currentId.current为undefined,可先打印viewableItems排查是否存在可见项,或item的id字段是否正确。
内容的提问来源于stack exchange,提问作者pfinferno
相关产品推荐
相关产品推荐

