在FlatList中使用分页实现CRUD功能的最佳方法是什么?

时间:2020-09-12 02:19:00

标签: react-native redux pagination redux-thunk react-native-flatlist

我目前正在构建一个非常基本的CRUD应用程序,用户可以在其中看到发布,删除和更新不同建议的信息。从长远来看,最好将分页渲染与大量数据一起使用,这样我就不必一次获取很多建议。

添加或创建新推荐时出现问题。我的应用与后端的分页不同步,因为它从数据库中删除/添加了一个项目。用FlatList和分页实现CRUD流的最佳方法是什么?

这是我的推荐减速器,操作和FlatList:

减速器:

import {
  SET_INITIAL_RECOMMENDATIONS,
  SET_NEXT_RECOMMENDATIONS,
  CREATE_RECOMMENDATION,
  UPDATE_RECOMMENDATION,
  DELETE_RECOMMENDATION,
} from "../actions/recommendations";

const recommendations = (state = [], action) => {
  switch (action.type) {
    case SET_INITIAL_RECOMMENDATIONS:
      return action.recommendations;

    case SET_NEXT_RECOMMENDATIONS:
      return [...state, ...action.nextRecommendations];

    case CREATE_RECOMMENDATION:
      state.pop();
      return [action.recommendation, ...state];

    case UPDATE_RECOMMENDATION:
      const recommendationIndex = state.findIndex(
        (recommendation) => recommendation.id === action.recommendationId
      );
      const updatedRecommendations = [...state];
      updatedRecommendations[recommendationIndex] = action.recommendation;
      return updatedRecommendations;

    case DELETE_RECOMMENDATION:
      return state.filter(
        (recommendation) => recommendation.id !== action.recommendationId
      );
    default:
      return state;
  }
};

export default recommendations;

动作:

export const fetchInitialRecommendations = () => {
  return (dispatch) => {
    dispatch({ type: IS_LOADING });
    fetch(`${BASE_URL}/recommendations?page=1`)
      .then((resp) => resp.json())
      .then((recommendations) => {
        dispatch({
          type: SET_INITIAL_RECOMMENDATIONS,
          recommendations: recommendations,
        });
        dispatch({ type: IS_NOT_LOADING });
      })
      .catch((err) => console.log(err));
  };
};

export const fetchNextRecommendations = (pageNumber) => {
  return (dispatch) => {
    dispatch({ type: RECOMMENDATIONS_ARE_LOADING });
    fetch(`${BASE_URL}/recommendations?page=${pageNumber}`)
      .then((resp) => resp.json())
      .then((recommendations) => {
        dispatch({
          type: SET_NEXT_RECOMMENDATIONS,
          nextRecommendations: recommendations,
        });
        dispatch({ type: RECOMMENDATIONS_ARE_NOT_LOADING });
      })
      .catch((err) => console.log(err));
  };
};

export const deleteRecommendation = (recommendationId, navigation) => {
  return (dispatch, getState) => {
    const userToken = getState().loggedInUser.jwt;

    const reqObj = {
      method: "DELETE",
      headers: {
        Authorization: `Berear ${userToken}`,
        Accepts: "application/json",
      },
    };

    fetch(`${BASE_URL}/recommendations/${recommendationId}`, reqObj)
      .then((resp) => resp.json())
      .then((data) => {
        if (data.status !== 200) {
          Alert.alert("Please Try Again.", data.error_messages[0], [
            { title: "OK" },
          ]);
        } else {
          dispatch({
            type: DELETE_RECOMMENDATION,
            recommendationId: recommendationId,
          });
          navigation.goBack();
        }
      })
      .catch((err) => console.log(err));
  };
};

我的FlatList实现:

import React, { Component, Fragment } from "react";
import {
  View,
  StyleSheet,
  FlatList,
  ActivityIndicator,
  RefreshControl,
} from "react-native";

import { connect } from "react-redux";
import {
  fetchInitialRecommendations,
  refreshInitialRecommendations,
  fetchNextRecommendations,
} from "../../../store/actions/recommendations";

import RecommendationCard from "../../../components/UI/browser/recommendations/RecommendationCard";

import colors from "../../../constants/colors";

class BrowserRecommendationsScreen extends Component {
  constructor() {
    super();

    this.state = {
      page: 1,
      refreshing: false,
    };
  }

  componentDidMount() {
    this.props.fetchInitialRecommendations();
  }

  handleRefresh = () => {
    this.setState({ refershing: true }, () =>
      this.props.refreshInitialRecommendations()
    );
    this.setState({ page: 1, refreshing: false });
  };

  loadMoreRecommendations = () => {
    this.setState(
      {
        page: this.state.page + 1,
      },
      () => this.props.fetchNextRecommendations(this.state.page)
    );
  };

  newRecommedationOnPress = () => {
    this.props.navigation.navigate("BrowserNewRecommendation");
  };

  render() {
    if (this.props.loader) {
      return (
        <View style={styles.activityIndicatorScreen}>
          <ActivityIndicator size="large" color={colors.primaryColor} />
        </View>
      );
    }
    return (
      <View style={styles.container}>
        <FlatList
          contentContainerStyle={styles.flatList}
          data={this.props.recommendations}
          renderItem={(item) => (
            <RecommendationCard
              key={item.id}
              id={item.id}
              recommendationData={item}
              navigation={this.props.navigation}
            />
          )}
          keyExtractor={(item) => item.id.toString()}
          showsVerticalScrollIndicator={false}
          refreshControl={
            <RefreshControl
              onRefresh={() => this.handleRefresh()}
              refreshing={this.props.recommendationsAreRefreshing}
            />
          }
          onEndReachedThreshold={0}
          onEndReached={this.loadMoreRecommendations}
          extraData={this.props.recommendations}
        />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  activityIndicatorScreen: {
    flex: 1,
    justifyContent: "center",
    alignContent: "center",
    backgroundColor: colors.secondaryLight,
  },
  container: {
    flex: 1,
    width: "100%",
    backgroundColor: colors.secondaryLight,
  },
  flatList: {
    justifyContent: "center",
    alignItems: "center",
    width: "100%",
    paddingBottom: 20,
  },
});

const mapStateToProps = (state) => {
  return {
    loader: state.loader,
    recommendationsAreLoading:
      state.recommendationsLoader.recommendationsAreLoading,
    recommendationsAreRefreshing:
      state.recommendationsLoader.recommendationsAreRefreshing,
    recommendations: state.recommendations,
  };
};

const mapDispatchToProps = (dispatch) => {
  return {
    fetchInitialRecommendations: () => dispatch(fetchInitialRecommendations()),
    refreshInitialRecommendations: () =>
      dispatch(refreshInitialRecommendations()),
    fetchNextRecommendations: (pageNumber) =>
      dispatch(fetchNextRecommendations(pageNumber)),
  };
};

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(BrowserRecommendationsScreen);

这回到我最初的问题,用FlatList和分页实现CRUD功能的最佳方法是什么?还是有什么解决方法?谢谢!

1 个答案:

答案 0 :(得分:0)

就我而言,每次执行诸如编辑,删除或添加新项之类的操作时。从该操作获得成功响应后,我总是从头开始加载数据(第1页)。