- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在使用 <FlatList>
时,我在尝试避免收到“VirtualizedList: You have a large list that is slow to update”警告时遇到了很多麻烦。带有 React-Native 的组件。
我已经做了大量的研究和 Google-Fu 来尝试一个解决方案,但是没有一个解决方案有帮助,甚至没有 this GitHub issue 上的解决方案。 .
要记住的事情:
shouldComponentUpdate() { return false; }
在我的列表项组件中,因此它们根本没有更新。 PureComponent
renderItem
组件不会在每次调用时重新初始化。 BottomTabNavigator
切换到单独的选项卡后才会出现警告。然后返回并滚动浏览我的列表;但这很令人困惑,因为当我这样做时,FlatList 屏幕组件不会重新呈现,列表项也不会。由于浏览到另一个选项卡时组件不会重新渲染,为什么会发生此错误?
const AppRoutes = [
{ name: "Home", Component: HomeScreen },
{ name: "Catalog", Component: CatalogScreen },
{ name: "Cart", Component: CartScreen }
];
export const StoreApp = () => {
return (
<NavigationContainer>
<StatusBar barStyle="dark-content" />
<Tabs.Navigator>
{AppRoutes.map((route, index) =>
<Tabs.Screen
key={index}
name={route.name}
component={route.Component}
options={{
headerShown: (route.name !== "Home") ?? false,
tabBarIcon: props => <TabIcon icon={route.name} {...props} />
}}
/>
)}
</Tabs.Navigator>
</NavigationContainer>
);
};
目录屏幕.tsx
import React from "react";
import { FlatList, SafeAreaView, Text, View, StyleSheet } from "react-native";
import { LoadingSpinnerOverlay } from "../components/LoadingSpinnerOverlay";
import { getAllProducts, ProductListData } from "../api/catalog";
class ProductItem extends React.Component<{ item: ProductListData }> {
shouldComponentUpdate() {
return false;
}
render() {
return (
<View>
{console.log(`Rendered ${this.props.item.name}-${Math.random()}`)}
<Text style={{height: 100}}>{this.props.item.name}</Text>
</View>
);
}
}
export class CatalogScreen extends React.PureComponent {
state = {
productData: []
};
componentDidMount() {
getAllProducts()
.then(response => {
this.setState({ productData: response.data });
})
.catch(err => {
console.log(err);
});
}
private renderItem = (props: any) => <ProductItem {...props} />;
private keyExtractor = (product: any) => `${product.id}`;
private listItemLayout = (data: any, index: number) => ({
length: 100,
offset: 100 * index,
index
});
render() {
const { productData } = this.state;
console.log("CATALOG RENDERED");
return (
<SafeAreaView style={styles.pageView}>
{!productData.length && <LoadingSpinnerOverlay text="Loading products..." />}
<View style={{backgroundColor: "red", height: "50%"}}>
<FlatList
data={productData}
removeClippedSubviews
keyExtractor={this.keyExtractor}
renderItem={this.renderItem}
getItemLayout={this.listItemLayout}
/>
</View>
</SafeAreaView>
);
}
};
const styles = StyleSheet.create({
pageView: {
height: "100%",
position: "relative",
}
});
由于我的组件和列表已优化并且我仍然收到错误,我开始相信这可能是 React Native 的实际问题 - 但如果有人能看到我做错了什么或任何解决方法,这个会有很大帮助!
CatalogScreen
不再出现警告组件包含在
NativeStackNavigator
中与一个单一的屏幕。我相信这可能表明这是
BottomTabNavigator
的问题。模块。
const AppRoutes = [
{ name: "Home", Component: HomeScreen },
{ name: "Catalog", Component: CatalogPage }, // Changed CatalogScreen to CatalogPage
{ name: "Cart", Component: CartScreen }
];
目录屏幕.tsx
const Stack = createNativeStackNavigator();
export class CatalogPage extends React.PureComponent {
render() {
return (
<Stack.Navigator>
<Stack.Screen
name="CatalogStack"
options={{ headerShown: false }}
component={CatalogScreen}
/>
</Stack.Navigator>
);
}
}
使用此解决方法,我将呈现堆栈导航组件而不是
CatalogScreen
直接组成。这解决了问题,但我不明白为什么这会有所作为。与 BottomTabNavigator 屏幕相比,React Native 在 Stack Navigation 屏幕中处理内存对象的方式是否不同?
最佳答案
我只是随机回答一个问题,但充其量只是一个猜测。
您在评论中链接到您的问题的视频使发生的事情更加清楚,那里发生了一些奇怪的事情。
对于像这样的普通列表,尤其是在移动设备上,您只想渲染和加载当前正在显示和可见的项目,您不想将所有可能项目的整个列表保留在内存中并一直渲染。这就是为什么你会使用回调之类的东西来呈现项目,以便列表可以在滚动时调用回调并只呈现它需要的项目。
这里说的是我能想到的一些随机的事情:
({prop1, prop2})
而不是 props
与 ...props
.如果您像这样解构 Prop ,它将在每次加载项目时创建一个新对象。如果平面列表不断调用回调并创建大量新对象,这可能是导致您的问题的罪魁祸首之一。这也可能是产品项目的一个问题,如果它看到它收到了一个新的 Prop 引用,这意味着它是一个不同的对象,那么它将不得不做一个浅层比较(即使它是一个纯组件),数百的 Prop 。那真的可以减慢它的速度。结果是它实际上不会重新渲染它,但它仍然会进行数百次浅对象比较,这是一个缓慢的过程。所以修复解构,我敢打赌这样的事情会导致性能问题。 this
. 关于javascript - "VirtualizedList: You have a large list that is slow to update"警告即使所有组件都已优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70059668/
错误:不变违规:VirtualizedList 包含一个单元格,该单元格本身包含多个与父列表方向相同的 VirtualizedList。您必须将唯一的 listKey 属性传递给每个同级列表。 所以我
我正在使用 react-native-google-places-autocomplete用于谷歌地方自动完成文本输入的包。但是在这里我每次点击地址后都会收到警告。 警告:: VirtualizedL
我正在尝试做这样的事情: 问题:该项目是使用 immutablejs 和 according to React Native Docs 构建的,我无法使用 FlatList 因此我无法使用该组件的 n
我是 React Native 的新手,对 FlatList 之间的区别感到困惑和 VirtualizedList . 所以, FlatList有什么区别和 VirtualizedList ? 我应该
升级到react-native 0.61后,我收到很多这样的警告: VirtualizedLists should never be nested inside plain ScrollViews w
当数据是数组时,我能够成功地从 ListView 迁移到 FlatList,但是如何为作为数据的对象实现新的 React Native List 类型? 我正在尝试使用 VirtualizedList
在使用 时,我在尝试避免收到“VirtualizedList: You have a large list that is slow to update”警告时遇到了很多麻烦。带有 React-Na
我从使用 FlatList 切换到 VirtualizedList,并收到错误 this.props.getItemCount 不是函数。当我运行调试器时,VirtualizedList.js 抛出异
为什么这个 VirtualizedList 在应该 365 度渲染时只渲染前 10 个项目?如果我传递一个包含超过 10 个项目的 data 变量,它工作正常,但当我使用 getItem 方法时失败。
当我使用 FlatList内部组件 ScrollView我看到一个警告: VirtualizedLists should never be nested inside plain ScrollView
我的 有问题和 成分。 Link to GIF of the current issue 观看简短的 GIF 后,您可能会注意到我收到了一条警告: VirtualizedLists should n
我有一个包含大量内容的平面列表,当我在调试器控制台上滚动10到15页后向下滚动时,我得到了以下信息: VirtualizedList: You have a large list that is sl
我是一名优秀的程序员,十分优秀!