#javascript #reactjs #react-native #react-hooks #react-native-flatlist
#javascript #reactjs #реагировать -родной #реагирующие хуки #react-native-flatlist
Вопрос:
В моем приложении у меня очень длинный список элементов. Вот как выглядит отдельный элемент:
{
"id": "3f05a9a7-3365-49bb-9879-c42b58c0f615",
"title": "Joviold",
"description": "adipisicing excepteur mollit occaecat excepteur labore Lorem excepteur proident ad"
}
Каждый элемент отображается с флажком и может включаться и выключаться. Я сохраняю список идентификаторов переключаемых элементов в checkedItems
переменной.
Проблема в том, что всякий раз, когда я нажимаю элемент в списке, переключение занимает несколько секунд.
Вот код:
import React, { useState } from 'react';
import { Text, View, TouchableOpacity, FlatList, StyleSheet } from 'react-native';
import { Card, Checkbox, Title, Paragraph } from 'react-native-paper';
import data from "./data";
const App = () => {
const [checkedItems, setCheckedItems] = useState([]);
const isChecked = (id) => {
return checkedItems.includes(id);
};
const toggleItem = (id) => {
if (isChecked(id)) {
setCheckedItems(checkedItems.filter(item => item !== id));
} else {
setCheckedItems([...checkedItems, id]);
}
};
return (
<View style={s.root}>
<FlatList
data={data}
keyExtractor={(item) => item.id}
renderItem={({ item }) => (
<TouchableOpacity onPress={() => toggleItem(item.id)}>
<Card>
<Card.Content style={s.content}>
<Checkbox status={isChecked(item.id) ? "checked" : "unchecked"} />
<View>
<Title>
{item.title}
</Title>
<Paragraph>
{item.description}
</Paragraph>
</View>
</Card.Content>
</Card>
</TouchableOpacity>
)}
/>
</View>
);
}
const s = StyleSheet.create({
root: {
flex: 1,
backgroundColor: '#ecf0f1',
},
content: {
flexDirection: "row"
}
});
export default App;
Попробуйте это здесь: https://snack.expo.io/@pavermakov/flatlist-with-checkboxes
Как вы можете видеть, в коде нет ничего особенного.Отображаемые элементы имеют небольшой вес. Переключение элемента не должно занимать так много времени.
Что я могу сделать для повышения производительности?
Ответ №1:
Первый способ оптимизации — извлечь функцию рендеринга из JSX и обернуть ее в useCallback .
const renderItem = useCallback(
({ item }) => (
<TouchableOpacity onPress={() => toggleItem(item.id)}>
<Card>
<Card.Content style={s.content}>
<Checkbox status={isChecked(item.id) ? "checked" : "unchecked"} />
<View>
<Title>
{item.title}
</Title>
<Paragraph>
{item.description}
</Paragraph>
</View>
</Card.Content>
</Card>
</TouchableOpacity>
), []
)
...
renderItem={renderItem}
Вы можете прочитать больше здесь об этой оптимизации и больше здесь .
Комментарии:
1. Это не очень помогает. Я попытался уменьшить количество отображаемых элементов до 50. Похоже, что список становится все медленнее по мере его роста. я думал, что количество элементов не влияет на FlatList, потому что, насколько я помню, он не отображает все элементы одновременно.