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

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 keyExtractor prop
    FlatList relies on this prop to identify unique items reliably. While your items have a key property, 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 your getItems function:

    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 uses items = items.reverse(), which mutates the original array. Since PureComponent does 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
    componentWillMount is deprecated—switch to componentDidMount instead. Also, clean up your Firebase listener to prevent memory leaks, and log state after it's actually updated (since setState is 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:30:47