React Native Expo中如何正确展示Bored API返回的单个随机活动
问题解决:Bored API返回内容重复显示的修复
问题描述
从处理多货币数组的API切换到Bored API(返回单个随机活动)后,点击搜索按钮会出现活动内容重复多次显示的情况。
问题原因
原代码中使用了Object.keys(json.activity).map(...)来处理数据,但json.activity是字符串类型的值,Object.keys()作用于字符串时会将每个字符作为独立的键返回,因此map循环会为字符串的每一个字符生成一个包含完整活动内容的对象,最终数组长度等于活动字符串的字符数,导致FlatList重复渲染多次相同内容。
修复方案
方案1:调整数据处理逻辑(保留FlatList)
直接将单个活动内容包装成包含一个元素的数组,替代原有的错误遍历逻辑:
import { StyleSheet, Text, View, FlatList, SafeAreaView, Button, ScrollView, StatusBar } from 'react-native'; import { useEffect, useState } from 'react'; const Item = ({ item }) => { return( <View> <Text>{item.value}</Text> </View> ) } export default function App() { const [data, setData] = useState([]); const searchForActivity = () => { fetch('http://www.boredapi.com/api/activity/') .then((res) => res.json()) .then((json) => { // 直接包装为单元素数组 setData([{ value: json.activity }]); }); } useEffect(() => { searchForActivity(); }, []); return ( <SafeAreaView> <ScrollView> <View style={styles.container}> <Text>Welcome to Activity Finder</Text> <FlatList data={data} renderItem={Item} /> <Button title='Search' onPress={searchForActivity} /> <StatusBar style="auto" /> </View> </ScrollView> </SafeAreaView> ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff', alignItems: 'center', justifyContent: 'center', }, });
方案2:简化渲染逻辑(移除FlatList)
因为返回的是单个活动,完全不需要使用FlatList,直接用Text组件显示即可,代码更简洁:
import { StyleSheet, Text, View, SafeAreaView, Button, ScrollView, StatusBar } from 'react-native'; import { useEffect, useState } from 'react'; export default function App() { const [activity, setActivity] = useState(''); const searchForActivity = () => { fetch('http://www.boredapi.com/api/activity/') .then((res) => res.json()) .then((json) => { setActivity(json.activity); }); } useEffect(() => { searchForActivity(); }, []); return ( <SafeAreaView> <ScrollView> <View style={styles.container}> <Text>Welcome to Activity Finder</Text> <Text style={styles.activityText}>{activity}</Text> <Button title='Search' onPress={searchForActivity} /> <StatusBar style="auto" /> </View> </ScrollView> </SafeAreaView> ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff', alignItems: 'center', justifyContent: 'center', padding: 20, }, activityText: { fontSize: 16, marginVertical: 20, textAlign: 'center', }, });
关键说明
- Bored API返回的是单个对象,其中
activity字段是字符串,不需要遍历处理 - 原代码的遍历逻辑仅适用于处理包含多个键值对的对象(如之前的多货币API),不适合单个字符串值的场景
内容的提问来源于stack exchange,提问作者DevSteph
相关产品推荐
相关产品推荐

