使用useEffect挂钩获取数据时,我在FlatList中收到警告。
这是重现此问题的完整组件:
import React, { useState, useEffect } from "react";
import {
Text,
View,
FlatList,
ActivityIndicator,
SafeAreaView,
Button
} from "react-native";
const Test = props => {
const [people, setPeople] = useState([]);
const [loading, setLoading] = useState(false);
const [page, setPage] = useState(1);
useEffect(() => {
setLoading(true);
fetch(`http://jsonplaceholder.typicode.com/photos?_start=${page}&_limit=20`)
.then(res => res.json())
.then(res => {
//console.log(res);
setPeople(people => [...people, ...res]);
setLoading(false);
});
}, [page]);
const loadMore = () => {
setPage(page + 20);
};
return (
<SafeAreaView style={{ flex: 1 }}>
<FlatList
data={people}
keyExtractor={item => item.id}
renderItem={({ item }) => (
<View>
<Text>{item.id}</Text>
<Text>{item.title}</Text>
</View>
)}
ListFooterComponent={
loading ? (
<ActivityIndicator />
) : (
<Button title="Load More" onPress={loadMore} />
)
}
/>
</SafeAreaView>
);
};
export default Test;
这是我收到的警告
VirtualizedList:您的列表很大,更新速度很慢-确保您的renderItem函数呈现遵循React性能最佳实践的组件,例如PureComponent,shouldComponentUpdate等。Object { “ contentLength”:4418, “ dt”:705, “ prevDt”:669, }
虽然它基本上告诉我使用PureComponent
或shouldComponentUpdate
,但是AFAIK都不能同时使用功能组件或useEffect
钩子,对吗?
尽管我没有注意到(巨大的)性能下降,但我仍然想知道是否存在解决此问题的解决方法。任何帮助,将不胜感激。非常感谢。
编辑:使用PureComponent 不能解决问题:
创建了PureComponentTest.js
import React from "react";
import { Text, View } from "react-native";
const PureComponentTest = props => {
return (
<View>
<Text>{props.id}</Text>
<Text>{props.title}</Text>
</View>
);
};
export default PureComponentTest;
在我的组件中,我更新了renderItem={renderItems}
:
const renderItems = itemData => {
return (
<PureComponentTest
id={itemData.item.id}
title={itemData.item.title}
/>
);
};
答案 0 :(得分:0)
我真的没有发现您的组件有任何问题。这是一个非常简单的纯组件。可能只是因为获取的数据太大。尝试减少每次获取的页面数。说5或10页
答案 1 :(得分:0)
警告可能是由于要获取useEffect,所以请查看下一份文档:
关于useEffect挂钩要记住的一些规则:
您不能在条件内调用钩子;挂钩必须插入 完全相同的顺序。将useEffect放在条件内 可以打破那个周期;您通过钩子传递的函数不能是 异步函数,因为异步函数隐式返回诺言, 并且useEffect函数要么不返回任何内容,要么不返回任何清理功能。
考虑使用它:
fetch(`http://jsonplaceholder.typicode.com/photos?_start=${page}&_limit=20`)
.then(res => res.json())
.then(res => {
//console.log(res);
setPeople(people => [...people, ...res]);
})
.catch(error=> console.error(error))
.finally(() => setLoading(false));