使用 axios 获取数据并渲染 flatList
fetching data with axios and rendering flatList
我一直在试用 Axios 和 React Native,但我遇到了麻烦。 flatList 不呈现数据并给我一个警告 'warning: Each child in a list should have a unique "key" prop.'
我已经在线查找了几个小时,但找不到解决方案。我能找到的最接近的事情是设置 keyExtractor,我就是这么做的。
这是我的代码:
import React, { useEffect, useState } from 'react';
import { ActivityIndicator, FlatList, Text, View } from 'react-native';
import Axios from 'axios';
export default App = () => {
const [isLoading, setLoading] = useState(true);
const [data, setData] = useState([]);
useEffect(() => {
Axios.get('https://reactnative.dev/movies.json')
.then(({data}) => setData({data}))
.catch((error) => console.error(error))
.finally(() => setLoading(false));
});
return (
<View style={{ flex: 1, padding: 24 }}>
{isLoading ? <ActivityIndicator/> : (
<FlatList
data={JSON.stringify(data)}
keyExtractor={({ id }, index) => id}
renderItem={({ item }) => (
<Text>{item.title}, {item.releaseYear}</Text>
)}
/>
)}
</View>
);
};
我明白这可能是一个非常简单的问题,但如果你能帮助我,我将不胜感激。
我认为值得一提的是它与 fetch 一起使用。所以我认为问题出在 axios.get 请求而不是 flatList.
这里是 API 如果它有任何用处:
{
"title": "The Basics - Networking",
"description": "Your app fetched this from a remote endpoint!",
"movies": [
{ "id": "1", "title": "Star Wars", "releaseYear": "1977" },
{ "id": "2", "title": "Back to the Future", "releaseYear": "1985" },
{ "id": "3", "title": "The Matrix", "releaseYear": "1999" },
{ "id": "4", "title": "Inception", "releaseYear": "2010" },
{ "id": "5", "title": "Interstellar", "releaseYear": "2014" }
]
}
编辑:在尝试了此处的答案后,它不再发出警告,而是呈现一个空列表。
在渲染项目中,您需要提供文本的键:
renderItem={({ item }) => (
<Text key={item.title}>{item.title}, {item.releaseYear}</Text>
)}
就是这样,假设item.title是唯一的。
为了提供更多关于为什么这是一个问题的上下文,React 使用键来识别列表中的哪些项目在渲染之间是相同的,因此它可以比在每个渲染上创建全新的项目做更少的工作。本质上,React 使用键来确定哪些元素是同一元素。因此,如果您在每次渲染之间更改键,React 将假定该元素是一个新元素并在安装新元素之前卸载旧元素。
可以使用索引作为键,但这比使用唯一标识符的性能要差。因为使用索引意味着如果您对列表进行排序或以其他方式重新排序,它必须做更多的工作来协调差异,而不仅仅是移动 dom 个节点。
编辑:
除了最初的问题,我已经解决了您遇到的其他问题。
useEffect
调用需要使用依赖项数组,因此不会在每次重新渲染时都调用它。
axios 调用的数据需要使用 data.movies 才能获取电影数组。
传递到 FlatList 的数据不需要被字符串化,因为这会导致它将每个字符串化字符呈现为一个新行(逗号)。
试试这个
FlatList
data={JSON.stringify(data)}
keyExtractor={(id, index) => index.toString()}
renderItem={({ item }) => (
<Text>{item.title}, {item.releaseYear}</Text>
)}
/>
我想你需要日志数据来调试。
第一:setData({data})
是错误的。
第二:不要使用JSON.stringify(data)
。
第三:keyExtractor={({ id }, index) => id}
是错误的
试试下面的代码
import React, { useEffect, useState } from 'react';
import { ActivityIndicator, FlatList, Text, View } from 'react-native';
import Axios from 'axios';
export default App = () => {
const [isLoading, setLoading] = useState(true);
const [data, setData] = useState([]);
useEffect(() => {
Axios.get('https://reactnative.dev/movies.json')
.then(({ data }) => {
console.log("defaultApp -> data", data.movies)
setData(data.movies)
})
.catch((error) => console.error(error))
.finally(() => setLoading(false));
}, []);
return (
<View style={{ flex: 1, padding: 24 }}>
{isLoading ? <ActivityIndicator /> : (
<FlatList
data={data}
keyExtractor={(item, index) => {
// console.log("index", index)
return index.toString();
}}
renderItem={({ item }) => {
console.log("item", item)
return (
<Text style={{ flex: 1, backgroundColor: 'red' }}>{item.title}, {item.releaseYear}</Text>
)
}}
/>
)}
</View>
);
};
keyExtractor={({ id }, index) => id.toString()}
密钥最初以数字形式出现,您必须将其转换为字符串。
我一直在试用 Axios 和 React Native,但我遇到了麻烦。 flatList 不呈现数据并给我一个警告 'warning: Each child in a list should have a unique "key" prop.'
我已经在线查找了几个小时,但找不到解决方案。我能找到的最接近的事情是设置 keyExtractor,我就是这么做的。
这是我的代码:
import React, { useEffect, useState } from 'react';
import { ActivityIndicator, FlatList, Text, View } from 'react-native';
import Axios from 'axios';
export default App = () => {
const [isLoading, setLoading] = useState(true);
const [data, setData] = useState([]);
useEffect(() => {
Axios.get('https://reactnative.dev/movies.json')
.then(({data}) => setData({data}))
.catch((error) => console.error(error))
.finally(() => setLoading(false));
});
return (
<View style={{ flex: 1, padding: 24 }}>
{isLoading ? <ActivityIndicator/> : (
<FlatList
data={JSON.stringify(data)}
keyExtractor={({ id }, index) => id}
renderItem={({ item }) => (
<Text>{item.title}, {item.releaseYear}</Text>
)}
/>
)}
</View>
);
};
我明白这可能是一个非常简单的问题,但如果你能帮助我,我将不胜感激。
我认为值得一提的是它与 fetch 一起使用。所以我认为问题出在 axios.get 请求而不是 flatList.
这里是 API 如果它有任何用处:
{
"title": "The Basics - Networking",
"description": "Your app fetched this from a remote endpoint!",
"movies": [
{ "id": "1", "title": "Star Wars", "releaseYear": "1977" },
{ "id": "2", "title": "Back to the Future", "releaseYear": "1985" },
{ "id": "3", "title": "The Matrix", "releaseYear": "1999" },
{ "id": "4", "title": "Inception", "releaseYear": "2010" },
{ "id": "5", "title": "Interstellar", "releaseYear": "2014" }
]
}
编辑:在尝试了此处的答案后,它不再发出警告,而是呈现一个空列表。
在渲染项目中,您需要提供文本的键:
renderItem={({ item }) => (
<Text key={item.title}>{item.title}, {item.releaseYear}</Text>
)}
就是这样,假设item.title是唯一的。
为了提供更多关于为什么这是一个问题的上下文,React 使用键来识别列表中的哪些项目在渲染之间是相同的,因此它可以比在每个渲染上创建全新的项目做更少的工作。本质上,React 使用键来确定哪些元素是同一元素。因此,如果您在每次渲染之间更改键,React 将假定该元素是一个新元素并在安装新元素之前卸载旧元素。
可以使用索引作为键,但这比使用唯一标识符的性能要差。因为使用索引意味着如果您对列表进行排序或以其他方式重新排序,它必须做更多的工作来协调差异,而不仅仅是移动 dom 个节点。
编辑: 除了最初的问题,我已经解决了您遇到的其他问题。
useEffect
调用需要使用依赖项数组,因此不会在每次重新渲染时都调用它。
axios 调用的数据需要使用 data.movies 才能获取电影数组。
传递到 FlatList 的数据不需要被字符串化,因为这会导致它将每个字符串化字符呈现为一个新行(逗号)。
试试这个
FlatList
data={JSON.stringify(data)}
keyExtractor={(id, index) => index.toString()}
renderItem={({ item }) => (
<Text>{item.title}, {item.releaseYear}</Text>
)}
/>
我想你需要日志数据来调试。
第一:setData({data})
是错误的。
第二:不要使用JSON.stringify(data)
。
第三:keyExtractor={({ id }, index) => id}
是错误的
试试下面的代码
import React, { useEffect, useState } from 'react';
import { ActivityIndicator, FlatList, Text, View } from 'react-native';
import Axios from 'axios';
export default App = () => {
const [isLoading, setLoading] = useState(true);
const [data, setData] = useState([]);
useEffect(() => {
Axios.get('https://reactnative.dev/movies.json')
.then(({ data }) => {
console.log("defaultApp -> data", data.movies)
setData(data.movies)
})
.catch((error) => console.error(error))
.finally(() => setLoading(false));
}, []);
return (
<View style={{ flex: 1, padding: 24 }}>
{isLoading ? <ActivityIndicator /> : (
<FlatList
data={data}
keyExtractor={(item, index) => {
// console.log("index", index)
return index.toString();
}}
renderItem={({ item }) => {
console.log("item", item)
return (
<Text style={{ flex: 1, backgroundColor: 'red' }}>{item.title}, {item.releaseYear}</Text>
)
}}
/>
)}
</View>
);
};
keyExtractor={({ id }, index) => id.toString()}
密钥最初以数字形式出现,您必须将其转换为字符串。