#javascript #react-native #firebase-realtime-database
# #javascript #react-native #firebase-realtime-database
Вопрос:
Я впервые узнаю о состоянии и следую простому руководству по созданию приложения react native. В руководстве не рассматривалось использование firebase, так что это то, что я собрал вместе. Он «работает», но не извлекает данные базы данных при первом рендеринге. Я знаю, что это из-за задержки во времени, необходимой для сбора данных и рендеринга моего приложения. Но я не знаю, как мне переместить логику, чтобы исправить это. Я чувствую, что должен использовать .тогда как-то? Или я делаю все это совершенно неправильно…
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;
Ответ №1:
К тому времени, когда вы переходите 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
Затем вызов приведет к повторному отображению (затронутого) Пользовательский интерфейс, и это покажет сообщения.
Это, конечно, означает, что вам нужно вытащить useState
хук из MessagesScreen
, чтобы он также был виден в том месте, где вы сейчас вызываете setMessages
.
Комментарии:
1. Большое вам спасибо, это имеет смысл. Моя проблема сейчас в том, что когда я вытащил хук useState, он говорит мне, что он должен быть в функциональном компоненте. Означает ли это, что мне нужно каким-то образом поместить мою логику db.ref() в свой собственный компонент?
2. Я давно не создавал функциональные компоненты, поэтому рекомендую поискать новое сообщение об ошибке. Но мое первое предположение — переместить загрузку данных в
function MessagesScreen(props) {
функции и / или, возможно, вuseEffect
хук.