[英]React Native - Components not loading
在 React Native 中遇到一個奇怪的問題 - 我正在嘗試構建一個卡片列表,其中每張卡片代表一張帶有用戶信息(例如名字、姓氏等)的卡片。
卡片是一個單獨的組件,它采用_id
道具。 然后在 Card 組件中使用_id
來獲取數據。 然后像這樣實例化卡片:
Card.js
import React, { useState, useEffect } from 'react';
import {
View,
Text,
Image,
StyleSheet
} from 'react-native';
const Card = (props) => {
const [bio, setBio] = useState(true)
const [email, setEmail] = useState(true)
const [firstName, setFirstName] = useState(true)
const [lastName, setLastName] = useState(true)
const [phoneNumber, setPhoneNumber] = useState(true)
const [photoData, setPhotoData] = useState(true)
const baseUrl = "node-js-backend-url"
const fileReaderInstance = new FileReader();
loadImage = (url, headers) => {
fetch(url, {headers})
.then(response => response.blob())
.then(blob => {
fileReaderInstance.readAsDataURL(blob);
fileReaderInstance.onload = () => {
base64Data = fileReaderInstance.result;
setPhotoData(base64Data);
}
})
.then(() => {
console.log("Card details: ")
console.log(firstName)
console.log(lastName)
})
.catch(error => {
console.log("Error getting image for card: " + props._id + ", token: " + props.token+ ", "+ error)
});
}
loadCardData = (url) => {
let headers = new Headers()
headers.append("Content-Type", "application/x-www-form-urlencoded");
headers.append("x-auth-token", props.token)
fetch(url, {headers})
.then(response => response.json())
.then(data => {
setFirstName(data.firstName ? data.firstName : null)
setLastName(data.lastName ? data.lastName : null)
setBio(data.bio ? data.bio : null)
setEmail(data.email ? data.email : null)
setPhoneNumber(data.phoneNumber ? data.phoneNumber : null)
var photoUrl = baseUrl + "/api/card/" + data._id + "/file/image/" + data.photo.filename;
loadImage(photoUrl, headers)
})
.catch(error => {
console.log("Error fetching card data for card: " + props._id + ", token: " + props.token + ", " + error)
});
}
useEffect(() => {
let url = baseUrl + "/api/card/" + props._id
loadCardData(url)
console.log("Successfully loaded card.")
}, []);
return (
<>
<View
style={cardStyles.outerView}
>
<View style={cardStyles.photoView}>
<Image
source={{
uri: photoData.length > 0 ? photoData : null
}}
style={cardStyles.portrait}
></Image>
</View>
<View style={cardStyles.infoView}>
<Text style={cardStyles.names}>{firstName} {lastName}</Text>
<Text style={cardStyles.bio}>{bio}</Text>
<Text style={cardStyles.contact}>{email}</Text>
<Text style={cardStyles.contact}>{phoneNumber}</Text>
</View>
</View>
</>
);
};
const cardStyles = StyleSheet.create({
outerView: {
backgroundColor: '#F9F8F8',
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.23,
shadowRadius: 2.62,
elevation: 4,
borderRadius: 10,
padding: 15,
flexDirection: "row",
justifyContent: "center",
alignItems: "center"
},
names: {
fontSize: 18,
margin: 5
},
bio: {
margin: 10
},
contact: {
fontSize: 14
},
photoView: {
flex: 0.425,
width: 100,
height: 100,
borderRadius: 250,
marginRight: 15,
backgroundColor:"#FFFFFF",
justifyContent: "center",
alignItems: "center"
},
portrait: {
flex: 1,
width: "100%",
height: "100%",
resizeMode: 'contain',
borderRadius: 100,
},
infoView: {
flex: 1
}
})
export default Card;
Connections.js
import React, { useState, useEffect } from 'react';
import { styles } from '../styles/styles'
import Card from '../components/Card'
import {
SafeAreaView,
View,
ScrollView,
Text,
StatusBar,
StyleSheet
} from 'react-native';
const ContactsPage: () => React$Node = () => {
const baseUrl = "node-js-backend-url"
const token = "[x-auth-token-for-testing]"
const [connections, setConnections] = useState([])
const [loading, setLoading] = useState()
loadConnections = () => {
let headers = new Headers()
headers.append("Content-Type", "application/x-www-form-urlencoded");
headers.append("x-auth-token", token)
let url = baseUrl + "user/connections"
console.log("url: " + url)
fetch(url, {headers})
.then(response => response.json())
.then(data => {
setConnections(data.connections)
setLoading(false)
})
.catch(error => {
console.log("Error fetching connections: " + error)
});
}
useEffect(() => {
setConnections([])
setLoading(true)
loadConnections()
}, []);
return (
<>
<StatusBar barStyle="dark-content" />
<SafeAreaView style={styles.container}>
<View style={styles.heading}>
<Text style={styles.headline}>Connections</Text>
</View>
<ScrollView style={styles.body, cardStyles.cardList}>
{/* {loading == true && <Text>Loading...</Text>}
{(loading == false && connections.length == 0) && <Text>You have no connections yet! Add some to get started...</Text>}
{(loading == false && connections.length > 0) && connections.map(connection => (<Card key={connection} _id={connection} token={token}></Card>))} */}
{/* {( loading == false */}
{/* <Card key="card1" _id="6005ef770aeb9b3a7035311f" token={token} style={cardStyles.card}></Card> */}
{/* <Card key="card2" _id="6011d9d39689ab00049fc6e8" token={token} style={cardStyles.card}></Card> */}
{/* <Card key="card3" _id="6005ef770aeb9b3a7035311f" token={token} style={cardStyles.card}></Card> */}
<Card key="card4" _id="6011d9d39689ab00049fc6e8" token={token} style={cardStyles.card}/>
<Card key="card5" _id="6005ef770aeb9b3a7035311f" token={token} style={cardStyles.card}/>
</ScrollView>
</SafeAreaView>
</>
);
};
const cardStyles = StyleSheet.create({
card: {
marginTop: 10,
marginBottom: 10
},
cardList: {
height: "80%"
}
})
export default ContactsPage;
結果是渲染了 2 張卡片,但只有最后一張卡片包含任何信息。 如果我只創建一張卡片,所有信息都會按預期顯示。 添加多於兩張卡會導致除最后一張之外的所有卡都未填充(即不顯示用戶數據)。
有趣的是,即使對於不顯示的卡片,也會加載正確的數據。 記錄每張卡數據的檢索顯示用戶數據已設置在 state 中。 此外,不應用卡片樣式的邊距。 這可能是什么情況,如何解決?
您將所有數據獲取函數聲明為全局變量(例如loadCardData
、 loadImage
、 loadConnections
),因為您沒有在它們前面添加像const
這樣的關鍵字來定義它們的 scope。
改成:
const loadCardData = (url) =>
並重復所有實例。
無關說明:您可能需要重新考慮對所有useState
掛鈎的默認 state 使用true
。 您稍后會進行真/假比較,最終將在值初始化之前返回true
。 考慮將它們初始化為類型的空版本,例如string
的useState("")
或未定義的類型。
沒有這個,他們 go 進入全局 scope 並最終僅捕獲最后出現的setName
等
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.