当其中一项发生更改时,我的 FlatListrenderItem
正在重新渲染每个项目。
在做了一些调试之后,我对保存项目 (+ React.memo
) 的状态变量进行了深度克隆,它现在工作正常,但不确定它是否是最佳解决方案。
小吃: https ://snack.expo.io/-419PhiUl
应用程序.js
import * as React from 'react';
import { View, StyleSheet, FlatList } from 'react-native';
import Constants from 'expo-constants';
import _ from 'lodash';
import Item from './components/Item';
const keyExtractor = item => item.id.toString();
export default function App() {
const [data, setData] = React.useState([
{id: 1, title: 'Post 1', liked: false, user: {name: 'A'}},
{id: 2, title: 'Post 2', liked: false, user: {name: 'B'}},
{id: 3, title: 'Post 3', liked: false, user: {name: 'C'}},
]);
/**
* Like / Unlike the item.
*/
const like = React.useCallback((id) => {
setData(state => {
let clonedState = [...state];
let index = clonedState.findIndex(item => item.id === id);
clonedState[index].liked = ! clonedState[index].liked;
return clonedState;
});
}, []);
/**
* Render items.
*/
const renderItem = React.useCallback(({item}) => (
<Item item={item} onLike={like} />
), []);
const deepClonedData = React.useMemo(() => _.cloneDeep(data), [data]);
return (
<View style={styles.container}>
<FlatList
data={deepClonedData}
renderItem={renderItem}
keyExtractor={keyExtractor}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
}
});
项目.js
import React from 'react';
import {
Text, TouchableOpacity, StyleSheet
} from 'react-native';
function Item({item, onLike}) {
const _onLike = React.useCallback(() => {
onLike(item.id);
}, []);
console.log('rendering', item.title);
return (
<TouchableOpacity onPress={_onLike} style={styles.item}>
<Text>{item.title} : {item.liked ? 'liked' : 'not liked'}</Text>
</TouchableOpacity>
);
}
const styles = StyleSheet.create({
item: {
marginVertical: 10,
backgroundColor: 'white',
padding: 15,
borderWidth: 1
}
});
const areEqual = (prevProps, nextProps) => {
return prevProps.item.liked === nextProps.item.liked;
}
export default React.memo(Item, areEqual);