[英]FlatList is re-rendering items everytime screen is scrolled
我有一个包含 300 个项目的列表。 我正在使用 FlatList 来呈现项目。
问题:
我尝试通过调整windowSize
、 maxToRenderPerBatch
来优化列表,但问题仍然存在。
您可以在下面的沙箱链接中查看代码。
先感谢您 !
https://codesandbox.io/s/gracious-dhawan-i4d51h?file=/src/App.js
下面是代码片段
const data = [
{
id: 1,
first_name: "Shaina",
last_name: "Osorio",
email: "sosorio0@a8.net"
},
{
id: 2,
first_name: "Ania",
last_name: "Cotilard",
email: "acotilard1@about.me"
},
{
id: 3,
first_name: "Hagen",
last_name: "Lisciandri",
email: "hlisciandri2@nature.com"
}
]
const isEqual = (prev, next) => { return true; }; const RenderItem = React.memo((props) => { const { id, first_name, email } = props; console.log("id >>> ", id); return ( <View style={{ padding: 5, backgroundColor: "lightblue", marginVertical: 3 }} > <Text>First Name: {first_name}</Text> <Text>Email: {email}</Text> </View> ); }, isEqual); function App() { return ( <View style={{ flex: 1 }}> <FlatList data={data} renderItem={({ item }) => ( <RenderItem id={item.id} first_name={item.first_name} email={item.email} /> )} initialNumToRender={15} maxToRenderPerBatch={15} keyExtractor={(item) => item.id} /> </View> ); } export default App;
在您的示例中,您正在您的 renderItem 中记录,因此当新元素进入渲染区域时,它会被记录。 滚动时会发生这种情况。 但这并不意味着整个列表都会被重新渲染。 只需在托管列表的组件中直接放置一个 conosle.log,您会看到它只渲染一次,这与 renderItem 不同,它是在每次滚动创建新项目时渲染的。
const App = ()=> {
console.log("Entire List Rerendered");
return (
<View style={{ flex: 1 }}>
<FlatList
data={data}
renderItem={rendering}
initialNumToRender={5}
maxToRenderPerBatch={5}
keyExtractor={(item) => item.id}
/>
</View>
);
}
Flashlist 可能会有所帮助,因为它会回收 renderItems 并且不会像 Flatlist 那样销毁它们。 但是你应该更好地测试它。
你能把它定义为一个单独的 function
const rendering = ({ item }) => {
return (
<RenderItem
id={item.id}
first_name={item.first_name}
email={item.email}
/>
)
}
然后在你的平面清单上调用它?
<FlatList
data={data}
renderItem={rendering}
initialNumToRender={15}
maxToRenderPerBatch={15}
keyExtractor={(item) => item.id}
/>
内联事件处理程序是匿名函数。 每次组件渲染时都会创建它们。
更新
提取你的 render 和 keyExtractor 函数,并像这样用 useCallback 包围它们
function App() {
const rendering = useCallback(({item}) => {
console.log("id >>> ", item.id);
return (
<View
style={{
padding: 5,
backgroundColor: "lightblue",
marginVertical: 3
}}
>
<Text>First Name : {item.first_name}</Text>
<Text>Email : {item.email}</Text>
</View>
)
}, []);
const keyExtractoring = useCallback((item) => {
return item.id.toString();
}, []);
return (
<View style={{ flex: 1 }}>
<FlatList
data={data}
renderItem={rendering}
initialNumToRender={5}
maxToRenderPerBatch={5}
keyExtractor={keyExtractoring}
/>
</View>
);
}
查看 Shopify 的 FlashList,他们说它比 Flatlist 优化得多。 也许它可以满足您的需求。 尝试没有害处:点击这里
import React from "react";
import { View, Text, StatusBar } from "react-native";
import { FlashList } from "@shopify/flash-list";
const DATA = [
{
title: "First Item",
},
{
title: "Second Item",
},
];
const MyList = () => {
return (
<FlashList
data={DATA}
renderItem={({ item }) => <Text>{item.title}</Text>}
estimatedItemSize={200}
/>
);
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.