首页 > 解决方案 > 将 Firebase 实时数据库与 React Native 应用程序集成

问题描述

我第一次学习状态,并按照一个简单的教程创建了一个反应原生应用程序。本教程没有介绍使用 firebase,所以这是我拼凑的。它“有效”,但不会在第一次渲染时提取数据库数据。我知道这是因为获取数据与我的应用程序渲染相比所花费的时间延迟。但我不知道我应该如何移动逻辑来解决它。我觉得我应该以某种方式使用 .then ?还是我做的这一切完全错了……

import {db} from '../../src/config.js';

let initialMessages = [];
db.ref().once('value', (snapshot) =>{
  snapshot.forEach((child)=>{
    child.forEach(function(childChildSnapshot) {
      initialMessages.push({
        id: childChildSnapshot.key,
        title: childChildSnapshot.val().title,
      })
    })
  })
})
.then()
.catch((error) => {console.error('Error:', error)});

function MessagesScreen(props) {
  const [messages, setMessages] = useState(initialMessages);
  return (
    <Screens>
      <View style={styles.wholeThing}>
         <FlatList
          data={messages}
          keyExtractor={(messages) => messages.id.toString()}
          renderItem={({ item }) => (
            <Card
              title={item.title}
              onPress={() => console.log("hi")}
            />
          )}
          ItemSeparatorComponent={ListItemSeparator}
          contentContainerStyle={styles.messagesList}
          refreshing={refreshing}
          onRefresh={}
        />
      </View>
    </Screens>
  );
}

export default MessagesScreen;

标签: javascriptreact-nativefirebase-realtime-database

解决方案


当你传递initialMessages给状态钩子(作为它的初始值)时,initialMessages.push(...)还没有调用。

相反,您需要setMessages在数据加载后调用:

db.ref().once('value', (snapshot) =>{
  snapshot.forEach((child)=>{
    child.forEach(function(childChildSnapshot) {
      initialMessages.push({
        id: childChildSnapshot.key,
        title: childChildSnapshot.val().title,
      })
    })
    setMessages(initialMessages);
  })
})

然后调用setMessages将重新呈现(受影响的)UI,这将显示消息。

这当然意味着您需要将useState钩子拉出MessagesScreen,以便在您现在调用的位置也可以看到它setMessages


推荐阅读