Flatlist 在状态更新时滚动到顶部 onEndReached

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

每个 TabView 中都有 TabView 和 Flatlists。在 flatlist prop onReachEnd 中,调用一个函数来更新状态。一旦执行 onRecahEnd,即使我还没有调用任何 API,平面列表也会滚动到顶部。状态更新正确,但不知道为什么它每次都滚动到顶部。

const Pending = ({orderData, loading, onEndReached}: any) => (
  <>
    {loading ? (
      <View style={[styles.tabContainer]}>
        <View style={{flexGrow: 1, justifyContent: 'center'}}>
          <ActivityIndicator color={COLORS.ACCENT} size={50} />
        </View>
      </View>
    ) : (
      <FlatList
        showsVerticalScrollIndicator={false}
        data={orderData}
        renderItem={({item}) => <RenderItem item={item} />}
        keyExtractor={(item, index) => `${item.id}-${index}`}
        contentContainerStyle={styles.flatListContent}
        ListEmptyComponent={
          !loading ? (
            <View style={styles.emptyContainer}>
              <Text style={styles.emptyText}>No pending orders available.</Text>
            </View>
          ) : null
        }
        onEndReached={onEndReached}
        onEndReachedThreshold={0.1}
        // ListFooterComponent={
        //   loadingMore && (
        //     <View style={styles.footerLoading}>
        //       <ActivityIndicator color={COLORS.ACCENT} size={40} />
        //     </View>
        //   )
        // }
      />
    )}
  </>
);

const Order = ({navigation}: any) => {
  const [index, setIndex] = useState(0);
  const [orderData, setOrderData] = useState([]);
  const {localData} = useContext<any>(AuthContext);
  const [loading, setLoading] = useState(true);
  const [page, setPage] = useState(0);
  const dispatch = useDispatch<AppDispatch>();

  const tabs = [
    {key: 'pending', title: 'Pending'},
    {key: 'confirmed', title: 'Confirmed'},
    {key: 'all', title: 'All'},
  ];

  const statusMap = ['pending', 'confirm', 'all'];

  const renderScenes = {
    pending: () => (
      <Pending
        loading={loading}
        orderData={orderData}
        onEndReached={handleEndReached}
      />
    ),
    confirmed: () => <Confirmed loading={loading} orderData={orderData} />,
    all: () => <All loading={loading} orderData={orderData} />,
  };

  const fetchOrders = async (status: string) => {
    if (localData) {
      try {
        setOrderData([]);
        const resp = await dispatch(
          ordersByPagination({
            data: {
              url: localData?.base_url,
              skip: 0,
              take: 10,
              apiVersion: localData?.api_version,
              status: status,
            },
          }),
        );
        setOrderData(resp?.payload);
      } catch (error) {
        console.error('Error fetching orders:', error);
      } finally {
        setLoading(false);
      }
    }
  };

  let status;
  useEffect(() => {
    status = statusMap[index];

    fetchOrders(status);
  }, [index]);

  const handleEndReached = () => {
    setPage(prevPage => prevPage + 1);
  };

  return (
    <React.Fragment>
      <StatusBar
        backgroundColor={COLORS.NEUTRAL_LIGHT}
        barStyle={'dark-content'}
      />
      <Header onPress={() => navigation.openDrawer()} title="Order History" />
      <View style={styles.tabContainer}>
        <TabView
          index={index}
          setIndex={setIndex}
          tabBarStyle={{marginHorizontal: 0, marginBottom: 5}}
          tabs={tabs}
          renderScenes={renderScenes}
        />
      </View>
    </React.Fragment>
  );
};
react-native react-native-flatlist
1个回答
0
投票

变化:

  • 避免重置订单数据。相反,在加载更多项目时向其附加新数据。
  • 修复 keyExtractor 以确保 FlatList 中每个项目的唯一键。
  • 通过使用页面状态在用户滚动时加载更多项目来正确处理分页。

    const Pending = ({orderData, loading, onEndReached}: any) => (
      <>
        {loading ? (
          <View style={[styles.tabContainer]}>
            <View style={{flexGrow: 1, justifyContent: 'center'}}>
              <ActivityIndicator color={COLORS.ACCENT} size={50} />
            </View>
          </View>
        ) : (
          <FlatList
            showsVerticalScrollIndicator={false}
            data={orderData}
            renderItem={({item}) => <RenderItem item={item} />}
            keyExtractor={(item, index) => `${item.id}-${index}`}
            contentContainerStyle={styles.flatListContent}
            ListEmptyComponent={
              !loading ? (
                <View style={styles.emptyContainer}>
                  <Text style={styles.emptyText}>No pending orders available.</Text>
                </View>
              ) : null
            }
            onEndReached={onEndReached}
            onEndReachedThreshold={0.1}
          />
        )}
      </>
    );
    
    const Order = ({navigation}: any) => {
      const [index, setIndex] = useState(0);
      const [orderData, setOrderData] = useState([]);
      const {localData} = useContext<any>(AuthContext);
      const [loading, setLoading] = useState(true);
      const [page, setPage] = useState(0);
      const dispatch = useDispatch<AppDispatch>();
    
      const tabs = [
        {key: 'pending', title: 'Pending'},
        {key: 'confirmed', title: 'Confirmed'},
        {key: 'all', title: 'All'},
      ];
    
      const statusMap = ['pending', 'confirm', 'all'];
    
      const renderScenes = {
        pending: () => (
          <Pending
            loading={loading}
            orderData={orderData}
            onEndReached={handleEndReached}
          />
        ),
        confirmed: () => <Confirmed loading={loading} orderData={orderData} />,
        all: () => <All loading={loading} orderData={orderData} />,
      };
    
      const fetchOrders = async (status: string) => {
        if (localData) {
          try {
            const resp = await dispatch(
              ordersByPagination({
                data: {
                  url: localData?.base_url,
                  skip: page * 10, // Adjust skip for pagination
                  take: 10,
                  apiVersion: localData?.api_version,
                  status: status,
                },
              }),
            );
            setOrderData(prevData => [...prevData, ...resp?.payload]); // Append new data
          } catch (error) {
            console.error('Error fetching orders:', error);
          } finally {
            setLoading(false);
          }
        }
      };
    
      let status;
      useEffect(() => {
        status = statusMap[index];
        fetchOrders(status);
      }, [index]);
    
      const handleEndReached = () => {
        setPage(prevPage => prevPage + 1); // Increment page number
      };
    
      return (
        <React.Fragment>
          <StatusBar
            backgroundColor={COLORS.NEUTRAL_LIGHT}
            barStyle={'dark-content'}
          />
          <Header onPress={() => navigation.openDrawer()} title="Order History" />
          <View style={styles.tabContainer}>
            <TabView
              index={index}
              setIndex={setIndex}
              tabBarStyle={{marginHorizontal: 0, marginBottom: 5}}
              tabs={tabs}
              renderScenes={renderScenes}
            />
          </View>
        </React.Fragment>
      );
    };

现在格式应该正确,我希望它有助于解决问题!

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