【问题标题】:React Native Flatlist gets endless loop onEndReached using reduxReact Native Flatlist 使用 redux 获得无限循环 onEndReached
【发布时间】:2020-03-12 19:15:41
【问题描述】:

我正在使用 react-native FlatList 组件来呈现列表。我从一个动作中获取虚拟数据,但我的分页没有按预期运行,当我使用 onEndReached 时,它会立即渲染所有内容。

我错过了什么?

查看我的展会 https://snack.expo.io/@thesvarta/19d294

这是我的行动

  import { FETCH_FEED, MORE_FEED, REFRESH_FEED } from './actionTypes';

export const fetchFeed = () => {
  return async (dispatch, getState) => {
    const url = 'https://reqres.in/api/users?page=' + 1;
    const response = await fetch(url, {
      method: 'GET',
    });
    if (!response.ok) {
      const errorResData = await response.json();
      let message = 'error';
      throw new Error(message);
    }
    const resData = await response.json();
    dispatch({
      type: FETCH_FEED,
      data: resData.data,
      page: 1,
      rows: 1,
      message: resData.MESSAGE,
    });
  };
};
export const fetchRefreshFeed = () => {
  return async (dispatch, getState) => {
    const url = 'https://reqres.in/api/users?page=' + 1;
    const response = await fetch(url, {
      method: 'GET',
    });
    if (!response.ok) {
      const errorResData = await response.json();
      let message = 'error';
      throw new Error(message);
    }
    const resData = await response.json();
    dispatch({
      type: REFRESH_FEED,
      refresh_data: resData.data,
      refresh_page: 1,
      refresh_rows: 1,
      refresh_message: resData.MESSAGE,
    });
  };
};
export const loadMoreFeed = page => {
  return async (dispatch, getState) => {
    const url = 'https://reqres.in/api/users?page=' + page;
    const response = await fetch(url, {
      method: 'GET',
    });
    if (!response.ok) {
      const errorResData = await response.json();
      let message = 'error';
      throw new Error(message);
    }
    const resData = await response.json();
    dispatch({
      type: MORE_FEED,
      more_data: resData.data,
      more_page: page,
      more_rows: 1,
      more_message: resData.MESSAGE,
    });
  };
};

我的减速器

import { FETCH_FEED, REFRESH_FEED, MORE_FEED } from '../actions/actionTypes';

const initialState = {
  data: [],
  error: null,
  page: 1,
  rows: 1,
  message: null,
};

export default (state = initialState, action) => {
  switch (action.type) {
    case FETCH_FEED:
      return {
        data: action.data,
        page: action.page,
        rows: action.rows,
        message: action.message,
      };
    case REFRESH_FEED:
      return {
        data: action.refresh_data,
        page: action.refresh_page,
        rows: action.refresh_rows,
      };
    case MORE_FEED:
      return {
        data: [...state.data, ...action.more_data],
        page: action.more_page,
        rows: action.more_rows,
      };
    default:
      return state;
  }
};

我的组件

import React, {
  useState,
  useEffect,
  useReducer,
  useCallback,
  getState,
} from 'react';
import { Navigation } from 'react-navigation';
import {
  StyleSheet,
  View,
  Text,
  StatusBar,
  TouchableHighlight,
  TouchableOpacity,
  FlatList,
  Image,
  Modal,
  Linking,
  ScrollView,
  Alert,
} from 'react-native';
import { useDispatch, useSelector } from 'react-redux';
import * as feedActions from '../../store/actions/feed';
const FeedScreen = props => {
  const [error, setError] = useState();
  const [refresh, setRefresh] = useState(false);
  const dispatch = useDispatch();
  const state = useSelector(state => state.feed);
  const loadFeed = useCallback(async () => {
    setError(null);
    try {
      await dispatch(feedActions.fetchFeed(state.page, state.rows));
    } catch (err) {
      setError(err.message);
    }
  }, [dispatch, setError]);

  useEffect(() => {
    loadFeed();
  }, [loadFeed]);
  const refreshFeed = useCallback(async () => {
    setError(null);
    setRefresh(true);
    try {
      await dispatch(feedActions.fetchRefreshFeed());
    } catch (err) {
      setError(err.message);
    }
    setRefresh(false);
  }, [dispatch, setError, setRefresh]);
  const morefeed = useCallback(async () => {
    setError(null);
    try {
      await dispatch(feedActions.loadMoreFeed(state.page + 1));
    } catch (err) {
      setError(err.message);
    }
  }, [dispatch, setError]);
  const renderRow = ({ item, index }) => {
    return (
      <View key={index}>
        <Text>{item.email}</Text>
      </View>
    );
  };
  if (error != null) {
    return (
      <View style={styles.centered}>
        <Text>An error occurred!</Text>
        <TouchableOpacity onPress={() => refreshFeed()}>
          Try again
        </TouchableOpacity>
      </View>
    );
  }
  return (
    <View style={styles.MainContainer}>
      <FlatList
        data={state.data}
        renderItem={renderRow}
        onRefresh={refreshFeed}
        refreshing={refresh}
        keyExtractor={(item, index) => index.toString()}
        onEndReached={morefeed}
        onEndReachedThreshold={0.5}
      />
    </View>
  );
};
const styles = StyleSheet.create({
  MainContainer: {
    flex: 1,
    backgroundColor: 'rgb(243,243,248)',
  },
});
export default FeedScreen;

【问题讨论】:

    标签: reactjs react-native redux react-redux react-native-flatlist


    【解决方案1】:

    您基本上需要一种方法来停止调度loadMoreFeed 操作。这就是几乎所有服务器端分页都包含下一页编号或总页数的原因。

    我已为您的操作添加了一个简单的页码检查:

    if(page <= totalPages) {
      const url = 'https://reqres.in/api/users?page=' + page;
      const response = await fetch(url, {
        method: 'GET',
      });
    
      if (!response.ok) {
        const errorResData = await response.json();
        let message = 'error';
        throw new Error(message);
      }
      const resData = await response.json();
      dispatch({
        type: MORE_FEED,
        more_data: resData.data,
        more_page: page,
        more_rows: 1,
        totalPages: resData.total_pages,
        more_message: resData.MESSAGE,
      });
    }
    

    我已经用修复编辑了你的零食,你可以在这个链接中找到它:https://snack.expo.io/rJmsZu0iS

    同样,这只是一种非常简单的跟踪页数的方法。您可能希望在生产环境中对其进行更改。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-26
      • 2018-04-05
      • 1970-01-01
      • 2022-09-30
      • 2020-07-09
      • 1970-01-01
      • 2019-03-09
      • 1970-01-01
      相关资源
      最近更新 更多