React Native SectionList 性能问题

问题描述 投票:0回答:2

我有一个像这样的 json 对象,来自我们的 api:

{
  "data": {
    "items": [
      {
        "id": 1646,
        "created_at": "2021-12-10T17:47:25+00:00",
      },
      {
        "id": 1640,
        "created_at": "2021-12-10T13:23:49+00:00",
      },
      {
        "id": 1610,
        "created_at": "2021-12-10T09:44:55+00:00",
      },
      {
        "id": 1609,
        "created_at": "2021-12-10T09:44:19+00:00",
      },
      {
        "id": 1608,
        "created_at": "2021-12-10T09:43:46+00:00",
      },
      {
        "id": 1607,
        "created_at": "2021-12-10T09:43:07+00:00",
      },
      {
        "id": 1606,
        "created_at": "2021-12-10T09:42:31+00:00",
      },
      {
        "id": 1605,
        "created_at": "2021-12-10T09:41:52+00:00",
      },
      {
        "id": 1604,
        "created_at": "2021-12-10T09:41:13+00:00",
      },
      {
        "id": 1601,
        "created_at": "2021-12-09T18:09:15+00:00",
      },
      {
        "id": 1600,
        "created_at": "2021-12-09T18:08:45+00:00",
      },
      {
        "id": 1599,
        "created_at": "2021-12-09T18:08:21+00:00",
      },
      {
        "id": 1598,
        "created_at": "2021-12-09T18:07:48+00:00",
      },
      {
        "id": 1594,
        "created_at": "2021-12-09T17:19:54+00:00",
      },
      {
        "id": 1591,
        "created_at": "2021-12-09T16:39:10+00:00",
      }
    ],
    "page": 1,
    "total": 71,
    "pages": 5,
    "perPage": 15
  }
}

我已使用此功能按日期对它们进行分组:

export const createGroups = (data: any, dateField: string) => {
  const groups = data?.reduce((grp: any, bundle: any) => {
    const date = bundle[dateField]?.split('T')[0];

    if (!grp[date]) {
      grp[date] = [];
    }
    grp[date].push(bundle);
    return grp;
  }, {});
  let groupArrays = {};
  if (groups) {
    groupArrays = Object.keys(groups).map(date => {
      return {
        date,
        data: groups[date],
      };
    });
  }
  return groupArrays;
};

返回此分组数组:

[
  {
    "date": "2021-12-10",
    "data": [
      {
        "id": 1646,
        "created_at": "2021-12-10T17:47:25+00:00"
      },
      {
        "id": 1640,
        "created_at": "2021-12-10T13:23:49+00:00"
      },
      {
        "id": 1610,
        "created_at": "2021-12-10T09:44:55+00:00"
      },
      {
        "id": 1609,
        "created_at": "2021-12-10T09:44:19+00:00"
      },
      {
        "id": 1608,
        "created_at": "2021-12-10T09:43:46+00:00"
      },
      {
        "id": 1607,
        "created_at": "2021-12-10T09:43:07+00:00"
      },
      {
        "id": 1606,
        "created_at": "2021-12-10T09:42:31+00:00"
      },
      {
        "id": 1605,
        "created_at": "2021-12-10T09:41:52+00:00"
      },
      {
        "id": 1604,
        "created_at": "2021-12-10T09:41:13+00:00"
      }
    ]
  },
  {
    "date": "2021-12-09",
    "data": [
      {
        "id": 1601,
        "created_at": "2021-12-09T18:09:15+00:00"
      },
      {
        "id": 1600,
        "created_at": "2021-12-09T18:08:45+00:00"
      },
      {
        "id": 1599,
        "created_at": "2021-12-09T18:08:21+00:00"
      },
      {
        "id": 1598,
        "created_at": "2021-12-09T18:07:48+00:00"
      },
      {
        "id": 1594,
        "created_at": "2021-12-09T17:19:54+00:00"
      },
      {
        "id": 1591,
        "created_at": "2021-12-09T16:39:10+00:00"
      }
    ]
  }
]

这是我的屏幕,其中包含部分列表:

import React, { useState } from 'react';
import { VStack, SectionList, Text, HStack, Center } from 'native-base';
import moment from 'moment';
import { useGetAllTransactions } from '../hooks';
import { translate } from '@locale';
import { TransactionCard } from '../components';
import { ActivityIndicator, SectionListData } from 'react-native';
import { createGroups } from 'lib/bundle';
import { Transaction } from 'models/order/transaction';

type GroupedTransaction = {
  title: string;
  data: Transaction[];
};

export default function EarningListScreen() {
  const {
    data,
    isLoading,
    hasNextPage,
    isFetchingNextPage,
    refetch,
    fetchNextPage,
  } = useGetAllTransactions();

  const [transactions, setTransactions] = useState<GroupedTransaction[]>([]);

  React.useEffect(() => {
    if (data?.items) {
      const bundle = createGroups(
        data.items,
        'created_at',
      ) as GroupedTransaction[];
      setTransactions(bundle);
    }
  }, [data]);

  const renderItem = ({ item }: { item: Transaction }) => {
    return (
      <TransactionCard>
          <TransactionCard.Item
            flex={3}
            label={translate('earnings.list.datetime')}
            text={moment(item.created_at).format('ddd, MMM DD HH:mm')}
          />
      </TransactionCard>
    );
  };

  const renderHeader = (item: {
    section: SectionListData<
      Transaction,
      { date: string; data: Transaction[] }
    >;
  }) => (
    <HStack>
      <Text fontWeight="bold">
        {moment(item.section.date).format('MMM YYYY ')}
      </Text>
    </HStack>
  );

  return (
    <VStack>
      <SectionList
        contentContainerStyle={{ flexGrow: 1 }}
        flexGrow={1}
        sections={transactions}
        keyExtractor={(item, index) => (item.id + index).toString()}
        renderItem={renderItem}
        renderSectionHeader={renderHeader}
        refreshing={isLoading}
        onRefresh={refetch}
        onEndReachedThreshold={0.5}
        onEndReached={() =>
          hasNextPage && !isFetchingNextPage && fetchNextPage()
        }
        ListEmptyComponent={() => null}
        showsVerticalScrollIndicator={false}
      />
    </VStack>
  );
}

但是SectionList存在性能问题。我认为我的 createGroups 函数有一些问题,我不知道为什么以及如何处理。

javascript list react-native native-base react-native-sectionlist
2个回答
0
投票
const renderItem = ({ item }: { item: Transaction }) => {
    return (
      <TransactionCard>
          <TransactionCard.Item
            flex={3}
            label={translate('earnings.list.datetime')}
            text={moment(item.created_at).format('ddd, MMM DD HH:mm')}
          />
      </TransactionCard>
    );
  };

需要在

中添加关键道具

0
投票
  1. 我也面临同样的问题。将日志保留在渲染项中并检查日志打印了多少次。

  2. 然后最初用

    React.memo
    包裹渲染项(将渲染项保留在单独的组件中),这样可以避免不必要的重新渲染并检查日志。

  3. 然后进一步使用

    useMemo
    useCallback
    ,它会改善更多

© www.soinside.com 2019 - 2024. All rights reserved.