I am trying to fill a component with database data - I have an image and some description that is fetched from Google Firestore. At the moment I am struggling because the component is being rendered before the data is fetched and put into the components.
My code is listed below. It is in another file and then is run in the file I want to display the data in. I also know that my data is being fetched from the database correctly because I am printing to the console and when I run the code, the right data is displayed in the console.
Thanks!
function DailyView({itemImage, itemEmotion, itemReason, itemMood, itemTime}) {
const db = getDatabase();
const getEmotions = ref(db, 'users/' global.uid);
onValue(getEmotions, (snapshot)=>{
var data = snapshot.val();
for (const value of Object.values(data)) {
console.log(value["entry"]["feeling"])
}
const numEntries = Object.keys(data).length
console.log(numEntries)
console.log(Object.values(data)[0]["entry"]["reason"])
global.item1Emotion = Object.values(data)[numEntries-1]["entry"]["feeling"]
global.item1Reason = Object.values(data)[numEntries-1]["entry"]["reason"]
global.item1Mood = Object.values(data)[numEntries-1]["entry"]["mood"]
global.item1Time = Object.values(data)[numEntries-1]["entry"]["time"]
global.item1Time = Moment(global.item1Time).format('D MMM YYYY - h:mma ')
global.item1Image = getImage(global.item1Emotion)
})
return (
<View style={styles.viewStyle}>
<Image style={styles.emotions} source={global.item1Image}/>
<View style={styles.ViewReasons}>
<Text style={styles.emotionText}>{global.item1Emotion}</Text>
<Text style={styles.emotionSub}>Reason: {global.item1Reason}</Text>
<Text style={styles.emotionSub}>Mood: {global.item1Mood}</Text>
<Text style={styles.emotionSub}>{global.item1Time}</Text>
</View>
</View>
);
}
CodePudding user response:
You can use a state to store the data from firestore and check if it is undefined. If so return nothing otherwise display the data.
const [data, setData] = useState()
...
if (!data) {
return <></>
}
return (
<View>
<Text>{data.text}</Text>
</View>
)
CodePudding user response:
You should look into React Suspense, it was created exactly to address your issue.
https://reactjs.org/docs/concurrent-mode-suspense.html
CodePudding user response:
You can use a boolean state to prevent rerender of component until data is fetched. Sample code:
const [loading, setLoading] = useState(false);
return (
{loading ? (
//Your code
):(
//Custom no data found component or something like that
)}
)