我目前正在Android上的一个react本地页面上工作,有一个要求,允许用户输入一些东西,并将其添加到一个列表中,最新的项目在顶部。我正在使用Flatlist来呈现这些文本,目前我遇到了性能问题。
在我父组件中:
const SomePage = () => {
...
const [myArray, setMyArray] = useState<SomeType[]>([]);
...
const addItem = (item) => {
let newData = { id: item.id, desc: item.desc, index: someCounter };
setMyArray([newData, ...myArray]);
}
用于呈现平面列表中每个项目的代码:
const renderItemList = useCallback(
({item, index}, someFunction) => {
const closeRow = (closeIndex: number) => {
// close an item when another is opened
if (
prevOpenedRow.current &&
prevOpenedRow.current !== row[closeIndex]
) {
prevOpenedRow.current.close();
}
prevOpenedRow.current = row[closeIndex];
};
const renderRightActions = (progress, dragX, someFunction) => {
const opacity = dragX.interpolate({
inputRange: [-80, 0],
outputRange: [1, 0],
extrapolate: 'clamp',
});
return (
<Animated.View style={[styles.swipedRow, {opacity}]}>
<Animated.View style={styles.deleteButton}>
<Pressable style={{alignItems: 'center'}} onPress={someFunction}>
<SvgDelete />
<Animated.Text style={styles.deleteButtonText}>
Delete
</Animated.Text>
</Pressable>
</Animated.View>
</Animated.View>
);
};
return (
<Swipeable
key={item.id}
overshootFriction={3}
onSwipeableWillOpen={() => {
someTextInputRef?.current?.blur();
}}
renderRightActions={(progress, dragX) =>
renderRightActions(progress, dragX, onClick)
}
onSwipeableOpen={() => closeRow(index)}
ref={ref => (row[index] = ref)}>
<View>
<View>
<Text>#{item.index}</Text>
<SvgDot /> // some image
<Text>{item.id}</Text>
<SvgDot /> // some image
<SvgSealDot
stroke={Colors.Black30}
/>
<Text>ID</Text>
</View>
<Text>{item.desc}</Text>
</View>
</Swipeable>
);
},
[row, myArray],
);
const someFunction = () => {
...
}
呈现FlatList的代码:
return (
<View>
...
<FlatList
showsVerticalScrollIndicator={true}
data={myArray}
renderItem={item =>
renderItemList(item, () => {
someFunction(item);
})
}
keyExtractor={item => {
return item.id.toString();
}}
removeClippedSubviews
</FlatList>
...
</View>
);
}
我注意到FlatList是此页面的一部分,如果此页面中有任何内容,则FlatList中的所有内容都将再次呈现,即使我为每个项目呈现使用useCallback
这是非常令人困惑的一部分,当我添加一个新的项目到数组中,首先页面重新呈现一次,因为一些 prop 改变
然后FlatList再次重新渲染,因为有一些新元素(所有元素都将重新渲染,这需要惊人的600 ms-1000 ms来重新渲染列表中的每个元素。列表中最多可能有200个项目
我能做些什么来防止这些东西重新渲染吗?我需要一个接一个地添加200个项目,每次插入列表都会导致页面重新渲染一次(包括FlatList中的所有内容),然后FlatList再次重新渲染所有内容。
我已经尝试了removeClippedSubviews,但它没有任何影响这个问题。
我也试过使用myArray.map(.一些useCallback函数来渲染),但一切仍然是重新渲染
只是寻找方法来停止一切从重新渲染,使应用程序可以添加到这个列表顺利一切
1条答案
按热度按时间vshtjzan1#
尝试使用BigList,这是React Native的高性能列表视图,支持复杂布局,使用类似的FlatList用法来简化替换。
示例
如果您有任何状态要在呈现器中使用,且您希望避免不必要重新呈现(在这种情况下),请使用usecallback