React Native 与 Expo 应用程序不呈现 FlatList
React Native with Expo app not rendering FlatList
我没有显示任何错误,但我的应用程序运行时出现空白页面。当开始放置一些 api 代码时,它开始呈现一个空白页面,我从另一个项目复制并粘贴了这些代码,它工作得非常完美,但由于某种原因,它拒绝在这里工作这就是我的代码的样子。这是我的 App.js 文件
import React from 'react'
import { StyleSheet, Text, View } from 'react-native'
import Screen from './app/components/Screen'
import ProductScreen from './app/screens/ProductScreen';
export default function App() {
return (
<Screen>
<ProductScreen />
</Screen>
)
}
那么这就是产品screen.js
import React, {useState, useEffect} from 'react'
import { FlatList, StyleSheet, ActivityIndicator, Text, View } from 'react-native'
import Card from '../components/Card';
export default function ProductScreen() {
const [products, setproducts] = useState([]);
const [loading, setloading] = useState(true);
const getProducts = async () => {
try {
const response = await fetch('https://fakestoreapi.com/products/1');
const data = await response.json();
setproducts(data);
} catch (error) {
console.log("Something went wrong in your code",error)
} finally {
setloading(false);
}
}
useEffect(() => {
getProducts();
}, []);
return (
<View>
{loading ? <ActivityIndicator/> : (
<FlatList
data={products}
keyExtractor={(id) => id}
renderItem={({item}) => (
<Card
title={item.title}
subtitle={item.description}
img={item.image}
/>
)}
/>
)}
</View>
)
}
const styles = StyleSheet.create({})
最后 card.js 文件
import { Image, StyleSheet, Text, TouchableOpacity, View } from 'react-native'
import AppText from './AppText';
export default function Card({title, subtitle, img}) {
return (
<View style={styles.container}>
<Image source={img} style={styles.image} />
<View style={styles.cardText}>
<AppText style={{color: "black"}}>{title}</AppText>
<AppText style={{color: "#4ecdc4"}}>{subtitle}</AppText>
</View>
</View>
)
}
我哪里出错了?
嗯,您的 Expo Snack 中有几个问题。首先你的表达:
{loading && <FlatList />}
是错误的,因为您将其设置为检查 true
的加载,而当您在 getProducts
中检索数据后将其设置为 false
。
能够再次使用:
import React, { useState, useEffect } from 'react'
import { FlatList, StyleSheet, View } from 'react-native'
import Card from '../components/Card'
export default function ProductScreen() {
const [products, setProducts] = useState([])
const [loading, setLoading] = useState(true)
const getProducts = async () => {
try {
const response = await fetch('https://fakestoreapi.com/products/5')
const data = await response.json()
setProducts([data])
setLoading(false)
} catch (error) {
console.log('Something went wrong in your code', error)
}
}
useEffect(() => {
getProducts()
}, [])
return (
<View style={styles.container}>
{!loading && products.length !== 0 && (
<View>
<FlatList
data={products}
keyExtractor={(_, id) => id.toString()}
renderItem={({ item }) => <Card title={item.title} subtitle={item.description} img={item.image} />}
/>
</View>
)}
</View>
)
}
const styles = StyleSheet.create({
container: {
backgroundColor: 'lightgrey',
flex: 1,
},
})
Image
的 Card
中存在另一个错误。传递图像时的每个内存 URL 应该使用 URI 设置:
<Image source={{ uri: img }} style={styles.image} />
您将面临的另一个问题是 ProductScreen
container
的 View
样式应该应用 flex: 1
,如上面的代码所示。
查看 snack.expo.dev/@vuyi/spontaneous-candy 的代码,您似乎缺少 return 中 ProductScreen 的条件渲染。
您的代码如下所示:
<View style={styles.container}>
{loading &&
<FlatList
data={[products]}
keyExtractor={(_, id) => id.toString()}
renderItem={({item}) =>
<Card
title={item.title}
subtitle={item.description}
img={item.image}
/>
}
/>
}
</View>
当它需要看起来像这样时:
<View style={styles.container}>
{loading ? null :
<FlatList
data={[products]}
keyExtractor={(_, id) => id.toString()}
renderItem={({item}) =>
<Card
title={item.title}
subtitle={item.description}
img={item.image}
/>
}
/>
}
</View>
添加该条件将阻止您的 Flatlist 组件在访问您正在获取的数据之前呈现。看起来您在原始 post 中是正确的,但在 Expo Snack 环境中却不是。
我没有显示任何错误,但我的应用程序运行时出现空白页面。当开始放置一些 api 代码时,它开始呈现一个空白页面,我从另一个项目复制并粘贴了这些代码,它工作得非常完美,但由于某种原因,它拒绝在这里工作这就是我的代码的样子。这是我的 App.js 文件
import React from 'react'
import { StyleSheet, Text, View } from 'react-native'
import Screen from './app/components/Screen'
import ProductScreen from './app/screens/ProductScreen';
export default function App() {
return (
<Screen>
<ProductScreen />
</Screen>
)
}
那么这就是产品screen.js
import React, {useState, useEffect} from 'react'
import { FlatList, StyleSheet, ActivityIndicator, Text, View } from 'react-native'
import Card from '../components/Card';
export default function ProductScreen() {
const [products, setproducts] = useState([]);
const [loading, setloading] = useState(true);
const getProducts = async () => {
try {
const response = await fetch('https://fakestoreapi.com/products/1');
const data = await response.json();
setproducts(data);
} catch (error) {
console.log("Something went wrong in your code",error)
} finally {
setloading(false);
}
}
useEffect(() => {
getProducts();
}, []);
return (
<View>
{loading ? <ActivityIndicator/> : (
<FlatList
data={products}
keyExtractor={(id) => id}
renderItem={({item}) => (
<Card
title={item.title}
subtitle={item.description}
img={item.image}
/>
)}
/>
)}
</View>
)
}
const styles = StyleSheet.create({})
最后 card.js 文件
import { Image, StyleSheet, Text, TouchableOpacity, View } from 'react-native'
import AppText from './AppText';
export default function Card({title, subtitle, img}) {
return (
<View style={styles.container}>
<Image source={img} style={styles.image} />
<View style={styles.cardText}>
<AppText style={{color: "black"}}>{title}</AppText>
<AppText style={{color: "#4ecdc4"}}>{subtitle}</AppText>
</View>
</View>
)
}
我哪里出错了?
嗯,您的 Expo Snack 中有几个问题。首先你的表达:
{loading && <FlatList />}
是错误的,因为您将其设置为检查 true
的加载,而当您在 getProducts
中检索数据后将其设置为 false
。
能够再次使用:
import React, { useState, useEffect } from 'react'
import { FlatList, StyleSheet, View } from 'react-native'
import Card from '../components/Card'
export default function ProductScreen() {
const [products, setProducts] = useState([])
const [loading, setLoading] = useState(true)
const getProducts = async () => {
try {
const response = await fetch('https://fakestoreapi.com/products/5')
const data = await response.json()
setProducts([data])
setLoading(false)
} catch (error) {
console.log('Something went wrong in your code', error)
}
}
useEffect(() => {
getProducts()
}, [])
return (
<View style={styles.container}>
{!loading && products.length !== 0 && (
<View>
<FlatList
data={products}
keyExtractor={(_, id) => id.toString()}
renderItem={({ item }) => <Card title={item.title} subtitle={item.description} img={item.image} />}
/>
</View>
)}
</View>
)
}
const styles = StyleSheet.create({
container: {
backgroundColor: 'lightgrey',
flex: 1,
},
})
Image
的 Card
中存在另一个错误。传递图像时的每个内存 URL 应该使用 URI 设置:
<Image source={{ uri: img }} style={styles.image} />
您将面临的另一个问题是 ProductScreen
container
的 View
样式应该应用 flex: 1
,如上面的代码所示。
查看 snack.expo.dev/@vuyi/spontaneous-candy 的代码,您似乎缺少 return 中 ProductScreen 的条件渲染。
您的代码如下所示:
<View style={styles.container}>
{loading &&
<FlatList
data={[products]}
keyExtractor={(_, id) => id.toString()}
renderItem={({item}) =>
<Card
title={item.title}
subtitle={item.description}
img={item.image}
/>
}
/>
}
</View>
当它需要看起来像这样时:
<View style={styles.container}>
{loading ? null :
<FlatList
data={[products]}
keyExtractor={(_, id) => id.toString()}
renderItem={({item}) =>
<Card
title={item.title}
subtitle={item.description}
img={item.image}
/>
}
/>
}
</View>
添加该条件将阻止您的 Flatlist 组件在访问您正在获取的数据之前呈现。看起来您在原始 post 中是正确的,但在 Expo Snack 环境中却不是。