当元素已添加到数组状态时,本机 FlatList 会重新呈现
react native FlatList re-renders when elements have been added to the array state
当我想更改数组状态时,FlatList 中的所有元素都会重新呈现。我已经检查了具有相同问题的其他问题,但我无法解决它。首先,问题出在我的主要项目中,但因为我无法解决它,所以我使用下面给出的示例创建了一个清晰的项目,但问题仍然存在。
在主项目中,KeyExtractor 返回了一个唯一的 ID。
import React, { useEffect, useState, memo } from 'react';
import { FlatList, StyleSheet, Text, View } from 'react-native';
export default function App() {
const [data, setData] = useState([...Array(5).keys()])
useEffect(() => {
setInterval(() => {
console.log("----------")
setData(oldArray => [...oldArray, Math.ceil(Math.random() * 5000)])
}, 2000)
}, [])
const RenderItem = memo(({ item }: { item: number }) => {
return (
<View>
{ console.log("render", item) }
<Text>{ item }</Text>
</View>
)
})
const renderItemHandler = ({ item }: { item: number }) => {
return <RenderItem item={item} />
}
const keyExtractor = (item: number) => item.toString();
return (
<View style={styles.container}>
<FlatList
style={{ width: 100, backgroundColor: "#7132a8" }}
data={data}
renderItem={renderItemHandler}
keyExtractor={keyExtractor}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
});
https://snack.expo.dev/@sibyl/flatlist-issue
React DevTools 截图
更新
更新代码以使用备忘录
更新
通过将使用备忘录的组件移动到应用程序功能之外解决了这个问题
const RenderItem = memo((props: { item: number }) => {
return (
<View key={props.item}>
{ console.log("render", props.item) }
<Text>{ props.item }</Text>
</View>
)
})
const renderItemHandler = ({ item }: { item: number }) => {
return <RenderItem item={item} />
}
export default function App() {....
呈现调用将始终尝试重新呈现组件的子项。
如果您使用的是函数式组件,您可以利用 React.memo
https://reactjs.org/docs/react-api.html#reactmemo 来防止重新渲染子组件
或 shouldComponentUpdate
用于旧学校 class 组件 https://reactjs.org/docs/react-component.html#shouldcomponentupdate
当我想更改数组状态时,FlatList 中的所有元素都会重新呈现。我已经检查了具有相同问题的其他问题,但我无法解决它。首先,问题出在我的主要项目中,但因为我无法解决它,所以我使用下面给出的示例创建了一个清晰的项目,但问题仍然存在。 在主项目中,KeyExtractor 返回了一个唯一的 ID。
import React, { useEffect, useState, memo } from 'react';
import { FlatList, StyleSheet, Text, View } from 'react-native';
export default function App() {
const [data, setData] = useState([...Array(5).keys()])
useEffect(() => {
setInterval(() => {
console.log("----------")
setData(oldArray => [...oldArray, Math.ceil(Math.random() * 5000)])
}, 2000)
}, [])
const RenderItem = memo(({ item }: { item: number }) => {
return (
<View>
{ console.log("render", item) }
<Text>{ item }</Text>
</View>
)
})
const renderItemHandler = ({ item }: { item: number }) => {
return <RenderItem item={item} />
}
const keyExtractor = (item: number) => item.toString();
return (
<View style={styles.container}>
<FlatList
style={{ width: 100, backgroundColor: "#7132a8" }}
data={data}
renderItem={renderItemHandler}
keyExtractor={keyExtractor}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
});
https://snack.expo.dev/@sibyl/flatlist-issue
React DevTools 截图
更新
更新代码以使用备忘录
更新 通过将使用备忘录的组件移动到应用程序功能之外解决了这个问题
const RenderItem = memo((props: { item: number }) => {
return (
<View key={props.item}>
{ console.log("render", props.item) }
<Text>{ props.item }</Text>
</View>
)
})
const renderItemHandler = ({ item }: { item: number }) => {
return <RenderItem item={item} />
}
export default function App() {....
呈现调用将始终尝试重新呈现组件的子项。
如果您使用的是函数式组件,您可以利用 React.memo
https://reactjs.org/docs/react-api.html#reactmemo 来防止重新渲染子组件
或 shouldComponentUpdate
用于旧学校 class 组件 https://reactjs.org/docs/react-component.html#shouldcomponentupdate