当用户使用React Native的FlatList滚动到末尾时,从Airtable批量加载超过100条记录

1wnzp6jl  于 2023-06-06  发布在  React
关注(0)|答案(2)|浏览(169)

Airtable在API调用时默认只提供100条记录,以加载超过100条记录,我使用了偏移地址,但当所有记录都被调用时,我希望在用户滚动到最后时批量显示它们,更多的记录应该被加载。
我所尝试的...

const apiKey = "API_KEY";
const baseId = "BaseId";
const tableName = "Table1";
const viewName = "Grid view";
const pageSize = 10;
const base = new Airtable({ apiKey }).base(baseId);

const Home = () => {
  const [records, setRecords] = useState([]);
  const [isLoading, setIsLoading] = useState(false);
  const [offset, setOffset] = useState(0);

  useEffect(() => {
    setIsLoading(true);
    loadRecords();
  }, []);

  async function loadRecords() {
    setIsLoading(true);

    const response = await base(tableName)
      .select({ view: viewName, pageSize, offset })
      .all();

    const newRecords = [...records, ...response];
    setRecords(newRecords);

    if (response.offset) {
      setOffset(response.offset);
    } else {
      setOffset(0);
    }

    setIsLoading(false);
    console.log("Loaded records:", response);
  }
  function renderRecord({ item }) {
    return <CardView img={item.fields.wallpaper} />;
  }

  function renderFooter() {
    return isLoading ? (
      <View style={styles.loader}>
        <ActivityIndicator size="large" />
      </View>
    ) : null;
  }

  function handleLoadMore() {
    if (!isLoading && offset !== undefined) {
      loadRecords();
    }
  }

  return (
    <View style={styles.container}>
      <FlatList
        data={records}
        renderItem={renderRecord}
        numColumns={numColumns}
        keyExtractor={(item) => item.id}
        ListFooterComponent={renderFooter}
        onEndReached={handleLoadMore}
        onEndReachedThreshold={0}
        initialNumToRender={pageSize}
      />
    </View>
  );
};

export default Home;

有了这个代码,所有的记录都是一次加载,而不是分批加载,有人能帮助我吗,我哪里出错了

wlsrxk51

wlsrxk511#

你可以使用下面的 prop 来帮助你存档你想要的东西
要让flatlist在用户滚动时在每个图块上呈现一定数量的组件,可以使用maxToRenderPerBatch
它是一个可以通过FlatList传递的VirtualizedList属性。此>控制每批呈现的项目数量,即每次滚动时呈现的下一个项目块。优点:设置一个更大的数字意味着滚动时更少的视觉空白区域(增加填充率)。缺点:每批处理更多的项目意味着更长的JavaScript执行时间,可能会阻止其他事件处理,如按下,损害响应。

<FlatList
            data={records}
            renderItem={renderRecord}
            numColumns={numColumns}
            getItemLayout={getItemLayout}
            initialNumToRender={2}
            maxToRenderPerBatch={2}
            windowSize={5}
            ListFooterComponent={renderFooter}
            initialNumToRender={2} <=== important lines
            maxToRenderPerBatch={2} <=== important lines
            ...
          />

您可以阅读这篇文章来帮助您优化flatlisthttps://reactnative.dev/docs/optimizing-flatlist-configuration

oxcyiej7

oxcyiej72#

import React, { useEffect, useState } from 'react';
import { View, FlatList, ActivityIndicator } from 'react-native';
import Airtable from 'airtable';
import CardView from './CardView';
import styles from './styles';

const apiKey = "API_KEY";
const baseId = "BaseId";
const tableName = "Table1";
const viewName = "Grid view";
const base = new Airtable({ apiKey }).base(baseId);

const Home = () => {
  const [records, setRecords] = useState([]);
  const [isLoading, setIsLoading] = useState(false);
  const [isFetchingMore, setIsFetchingMore] = useState(false);
  const [offset, setOffset] = useState(0);
  const numColumns = 2; // Specify the number of columns for the FlatList

  useEffect(() => {
    setIsLoading(true);
    loadRecords();
  }, []);

  async function loadRecords() {
    setIsLoading(true);
    setIsFetchingMore(true);

    try {
      const response = await base(tableName)
        .select({ view: viewName, pageSize: records.length + 10, offset })
        .all();

      setRecords(response);
      setIsLoading(false);
      setIsFetchingMore(false);
      console.log("Loaded records:", response);
    } catch (error) {
      console.error("Error loading records:", error);
      setIsLoading(false);
      setIsFetchingMore(false);
    }
  }

  function renderRecord({ item }) {
    return <CardView img={item.fields.wallpaper} />;
  }

  function renderFooter() {
    return isFetchingMore ? (
      <View style={styles.loader}>
        <ActivityIndicator size="large" />
      </View>
    ) : null;
  }

  function handleLoadMore() {
    if (!isFetchingMore) {
      setOffset(records.length);
      loadRecords();
    }
  }

  return (
    <View style={styles.container}>
      <FlatList
        data={records}
        renderItem={renderRecord}
        numColumns={numColumns}
        keyExtractor={(item) => item.id}
        ListFooterComponent={renderFooter}
        onEndReached={handleLoadMore}
        onEndReachedThreshold={0.5} // Adjust the threshold as per your requirement
        initialNumToRender={10} // Specify the initial number of records to render
      />
    </View>
  );
};

export default Home;

pageSize在每次加载时被动态地设置为records.length + 10以获取更多的记录。在这种情况下不使用偏移。相反,records.length作为获取新记录的起始索引。isFetchingMore状态用于防止多个同时获取请求。
当用户滚动到列表的末尾时,将调用handleLoadMore函数,该函数将触发loadRecords函数,以根据增加的pageSize获取更多记录。renderFooter函数在获取新记录时显示活动指示符。
希望这会有帮助!!

相关问题