React Native+Firebase:FlatList重渲染异常与重复键错误问题
Hey there, let's tackle these two FlatList issues with your React Native + Firebase Realtime Database setup one by one!
1. Fixing the "Duplicate Keys" Error
Even though you're using Firebase's unique snap.key for each list item, there's a common gotcha with FlatList that might be causing this error:
Explicitly define the
keyExtractorprop
FlatList relies on this prop to identify unique items reliably. While your items have akeyproperty, explicitly setting this prop removes any ambiguity in how React Native processes the keys. Update your FlatList like this:<FlatList data={this.state.data} renderItem={({item}) => <MyListItem item={item} />} keyExtractor={(item) => item.key} />Add a safeguard against accidental duplicates
Since you've confirmed keys are unique in logs, this is a secondary check, but it never hurts to ensure you're not pushing duplicate items into your array. Tweak yourgetItemsfunction:getItems = (snap, items) => { snap.forEach((child) => { const isDuplicate = items.some(i => i.key === child.key); if (!isDuplicate) { items.push({ key: child.key, status: child.val().status, location: child.val().location, }); } }); };
2. Fixing the Occasional Non-Rerendering on Scroll
This issue ties directly to how you're updating your state and using React.PureComponent:
Avoid mutating the original array
Your current code usesitems = items.reverse(), which mutates the original array. SincePureComponentdoes a shallow comparison of state, it won't detect a change (the array reference stays the same) and skips re-rendering. Instead, create a copy of the array before reversing:// Replace items = items.reverse(); with this: const reversedItems = [...items].reverse(); this.setState({data: reversedItems});Fix your listener lifecycle and async state logging
componentWillMountis deprecated—switch tocomponentDidMountinstead. Also, clean up your Firebase listener to prevent memory leaks, and log state after it's actually updated (sincesetStateis asynchronous):componentDidMount() { this.makeRemoteRequest(); } componentWillUnmount() { // Clean up the Firebase listener when the component unmounts DB.off('value'); } makeRemoteRequest = () => { DB.on('value', (snap) => { const items = []; this.getItems(snap, items); const reversedItems = [...items].reverse(); this.setState({data: reversedItems}, () => { // Log only after state has been updated console.log(this.state.data); }); }); }
Give these changes a shot—they should resolve both the duplicate key errors and the occasional non-rerendering issue. Let me know if you hit any other roadblocks!
内容的提问来源于stack exchange,提问作者user8951490

