问题
I'm getting data from firebase databse in console that look like this. [{ "isDonor": true, "name": "Nadi", "photo": "https://gre", "uid": "2ZE" }, { "email": "mmaz", "isDonor": true, "name": "Mz", "photo": "https://gra", "uid": "Cb" }]
I want to create cards of each objects but how to accomplish that as data is fetched after some time?
I want to render it like this
Ihave checked other answres but they are mostly from class component.
I have tried using useEffect
hook but couldn't implement it
here is my code
import * as React from 'react';
import {Text, View, StyleSheet, Image} from 'react-native';
import database from '@react-native-firebase/database';
const donorsData = [];
database()
.ref('users')
.orderByChild('isDonor')
.equalTo(true)
.once('value')
.then((results) => {
results.forEach((snapshot) => {
// console.log(snapshot.key, snapshot.val());
// console.log(snapshot.val());
donorsData.push(snapshot.val());
});
// console.log('aft', donorsData);
});
export default function New() {
return (
<View style={styles.container}>
{donorsData.map((v, i) => {
return (
<View
key={v.uid}
style={{
backgroundColor: 'white',
padding: 10,
margin: 5,
borderRadius: 10,
}}>
<Text>{v.name}</Text>
<Text>{v.email}</Text>
<Image source={{uri: v.photo}} style={{height: 150, flex: 1}} />
</View>
);
})}
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#ecf0f1',
padding: 8,
backgroundColor: 'lightblue',
},
});
回答1:
import React, { useState, useEffect } from "react";
import { Text, View, StyleSheet, Image } from "react-native";
import database from "@react-native-firebase/database";
export default function New() {
const [data, setData] = useState([]);
useEffect(() => {
const donorsData = [];
database()
.ref("users")
.orderByChild("isDonor")
.equalTo(true)
.once("value")
.then((results) => {
results.forEach((snapshot) => {
donorsData.push(snapshot.val());
});
setData(donorsData);
});
}, []);
return (
<View style={styles.container}>
{data?.map((v, i) => {
return (
<View
key={v.uid}
style={{
backgroundColor: "white",
padding: 10,
margin: 5,
borderRadius: 10,
}}
>
<Text>{v.name}</Text>
<Text>{v.email}</Text>
{ v.photo && <Image source={{ uri: v.photo }} style={{ height: 150, flex: 1 }} />}
</View>
);
})}
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#ecf0f1",
padding: 8,
backgroundColor: "lightblue",
},
});
回答2:
Have a try with the below code...
import React, { useState, useEffect } from 'react';
import {Text, View, StyleSheet, Image} from 'react-native';
import database from '@react-native-firebase/database';
export default function New() {
const [donorsData, setDonorsData] = useState([]);
const [isLoading, setIsLoading] = useState(false);
const getDataHandler = async () => {
try {
setIsLoading(true)
database()
.ref('users')
.orderByChild('isDonor')
.equalTo(true)
.once('value')
.then((results) => {
setIsLoading(false);
const data = results.map((snapshot) => {
return snapshot.val()
});
setDonorsData([...data]);
}).catch(err => {
setIsLoading(false);
});
} catch(err) {
setIsLoading(false)
console.log("error : ", err.message);
}
}
useEffect(() => {
getDataHandler()
}, []);
if (isLoading) {
return (
<View>
<ActivityIndicator size="large" color="black" />
</View>
)
}
return (
<View style={styles.container}>
{
donorsData
.map((v, i) => {
return (
<View
key={v.uid}
style={{
backgroundColor: 'white',
padding: 10,
margin: 5,
borderRadius: 10,
}}
>
<Text>{v.name}</Text>
<Text>{v.email}</Text>
<Image source={{uri: v.photo}} style={{height: 150, flex: 1}} />
</View>
);
}
)}
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#ecf0f1',
padding: 8,
backgroundColor: 'lightblue',
},
});
回答3:
Here is a simple working example on useEffect to fetch data and display cards based on the data.
Expo => https://snack.expo.io/DYrvw6hOn
import React, {useState, useEffect} from 'react';
import { Text, View, StyleSheet } from 'react-native';
import Constants from 'expo-constants';
// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';
export default function App()
{
const [data, setData] = useState([])
const sampleData = [{id:0, title:"One"}, {id:1, title: "Two"}]
useEffect(() =>
{
setTimeout(() =>
{
setData(sampleData)
}, 3000)
}, [])
const card = data.length > 0
? data.map(item =>
{
return <Card style = {styles.cardStyle}>
<Text>{item.id} - {item.title}</Text>
</Card>
})
: <Text>Loading...</Text>
return (
<View style={styles.container}>
{card}
</View>
);
}
const styles = StyleSheet.create({
container:
{
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
},
cardStyle:
{
backgroundColor: 'lightblue',
padding: 20,
margin: 20
}
});
回答4:
you have to use a state to make the component updates when you get the data you desire. Your code code should be like this:
import React, {useEffect, useState} from 'react';
import {Text, View, StyleSheet, Image} from 'react-native';
import database from '@react-native-firebase/database';
export default function New() {
const [data, setData] = useState([])
const getData = async () => {
const donorsData = [];
database()
.ref('users')
.orderByChild('isDonor')
.equalTo(true)
.once('value')
.then((results) => {
results.forEach((snapshot) => {
// console.log(snapshot.key, snapshot.val());
// console.log(snapshot.val());
donorsData.push(snapshot.val());
});
// console.log('aft', donorsData);
});
setData(donorsData)
}
useEffect(()=>{
getData()
},[])
return (
<View style={styles.container}>
{data.lenght>0 && data.map((v, i) => {
return (
<View
key={v.uid}
style={{
backgroundColor: 'white',
padding: 10,
margin: 5,
borderRadius: 10,
}}>
<Text>{v.name}</Text>
<Text>{v.email}</Text>
<Image source={{uri: v.photo}} style={{height: 150, flex: 1}} />
</View>
);
})}
</View>
);
}
来源:https://stackoverflow.com/questions/66061765/how-to-render-data-fecthed-from-firebase-database-in-react-native-functional-com