FlatList медленно обновляется для отдельного элемента

#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, потому что, насколько я помню, он не отображает все элементы одновременно.