Hamed Ezati
Hamed Ezati

Reputation: 79

How to combine the previous data with the new data in React and display it at the same time

I'm newbie to Reactjs. The problem I'm encountered:

I want to capture and display new data when I scroll down

I take the data every time I go down and save it in Redax, but because it has pagination, it only shows 10 and does not add to the previous one.

this is my code

import { memo, useEffect, useState } from "react";
import Collapse from "@kunukn/react-collapse";
import CustomHeader from "SharedComponents/CustomHeader";
import InfiniteScroll from "react-infinite-scroller";

import "./styles.scss";

import Item from "./Components/Item/Item";
import { dispatchItemToRedux, getListServiceTransactions } from "Redux/Actions";
import { useDispatch, useSelector } from "react-redux";
import CircleLoading from "SharedComponents/Loading/CircleLoading";
import EmptyList from "./Components/EmptyList";
import ReducerTypes from "Redux/Types/ReducerTypes";

const Page = () => {
  const ListServiceTransactions = useSelector(
    (state) => state.app.ListServiceTransactions
  );

  const dispatch = useDispatch();
  const [loading, setLoading] = useState(false);
  const [type, setType] = useState("");
  const [open, setOpen] = useState(false);

  const transactionItems = ListServiceTransactions?.items?.data;
  const transactionPagination = ListServiceTransactions?.items;
  const typeFilters = ListServiceTransactions?.type_filters;
  const resultFilters = [];

  useEffect(() => {
    setLoading(true);
    dispatch(getListServiceTransactions(null, 1));
    setLoading(false);
  }, []);


  const handleLoadMore = () => {
   
    const {
      total,
      per_page,
      current_page,
      next_page_url,
    } = transactionPagination;
    if (total > per_page && next_page_url) {
      dispatch(getListServiceTransactions(type, current_page + 1)).then(
        (res) => {
          transactionItems.push(res);
        }
      );
    }

 
  };

 

  const clickFilter = (value) => {
    dispatch(getListServiceTransactions(type, 1));
    setLoading(true);

    setOpen(false);
    setLoading(false);
  };



  return (
    <div className="list-transactions-screen">
      <CustomHeader title="لیست تراکنش های خدمات" />
      <div className="p-4">
        <div className="box-filter-tarnsactions mb-3">
          <div className="button-open-collapse">
            <div
              className={`box-value-filter ${
                width && open == true ? "animation-filter" : null
              }`}
            >
              {typeTitle}
            </div>
            <button className="btn-filter-tarnsactions" onClick={OpenBox}>
              ||
            </button>
          </div>
          <Collapse
            isOpen={open}
            transition="height 400ms cubic-bezier(0.4, 0, 0.2, 1)"
          >
            {resultFilters
              ? resultFilters.map((typeItem) => {
                  return (
                    <p
                      className="m-0 my-2 p-2 bg-white  border rounded"
                      onClick={() => clickFilter(typeItem)}
                    >
                      {typeItem.label}
                    </p>
                  );
                })
              : null}
          </Collapse>
        </div>
        <div className="all-tarnsactions-list">
          {!loading ? (
            transactionItems?.length > 0 ? (
              transactionItems ? (
                <InfiniteScroll
                  pageStart={1}
                  loadMore={handleLoadMore}
                  hasMore={true}
                  threshold={200}
                  loader={
                    !transactionPagination.next_page_url &&
                    transactionPagination.next_page_url === null ? null : (
                      <CircleLoading key={0} />
                    )
                  }
                >
                  {transactionItems.map((item) => {
                    return <Item item={item} />;
                  })}
                </InfiniteScroll>
              ) : (
                <CircleLoading />
              )
            ) : (
              <EmptyList />
            )
          ) : (
            <CircleLoading />
          )}
        </div>
      </div>
    </div>
  );
};

export default memo(Page);


enter code here

this is my action

    function getListServiceTransactions(
  type: any = null,

  page: number = 1,
 
) {
  return function (dispatch: ReduxDispatch, getState: ReduxGetState) {
    return new Promise(function (resolve, reject) {
      const params = {
        type: type,
        page: page,
      };

      axios({
        method: "GET",
        baseURL: Api.PUBLIC_API_V2,
        url: "other-services/transaction/list",
        params: params,
      })
        .then((res) => {
          dispatch(
            dispatchItemToRedux({
              type: ReducerTypes.LIST_SERVICE_TRANSACTIONS,
              payload: res.data.data,
            })
          );

          resolve(res);
          console.log("raft to action v req zad v in response", res);
        
        })
        .catch((err) => {
          reject(err);
        });
    });
  };
}

this is my reducer



    
function appReducer(state = INITIAL_STATE, action) {
  switch (action.type) {
    case ReducerTypes.SET_STEPPER:
      return { ...state, activeStep: action.payload };
    case ReducerTypes.TOGGLE_BUTTON_SPINNER:
      return { ...state, showButtonSpinner: action.payload.value };
    case ReducerTypes.LOCATION_PERMISSION:
      return { ...state, locationPermission: action.payload };
    case ReducerTypes.TOGGLE_LOADING:
      return { ...state, showLoading: action.payload.value };
    case ReducerTypes.TOGGLE_LOADING_EVERLAY:
      return { ...state, showLoadingEverlay: action.payload.value };
    case ReducerTypes.TOGGLE_SHOW_SIDEBAR:
      return { ...state, showSidebar: action.payload.value };
    case ReducerTypes.TOGGLE_SHOW_NOTIFICATION:
      return { ...state, showNotification: action.payload.value };
    case ReducerTypes.TOAST_MESSAGE_MODAL:
      return {
        ...state,
        toastMessage: { ...action.payload.toastMessage },
      };
    case ReducerTypes.MAIN_PAGE_DATA:
      return {
        ...state,
        mainPageState: action.payload,
      };
    case ReducerTypes.CAMPAIGN_BUSINESSES_DATA:
      return {
        ...state,
        campaignBusinessesData: action.payload,
      };
    case ReducerTypes.CAMPAIGN_BUSINESSES_ITEMS:
      return {
        ...state,
        campaignBusinessesItems: action.payload,
      };
    case ReducerTypes.LOADING_PINS:
      return { ...state, loadingPins: action.payload.value };
    case ReducerTypes.APP_CATEGORIES:
      return {
        ...state,
        categories: action.payload.categories,
        structuredCategories: action.payload.structuredCategories,
      };
    case ReducerTypes.APP_DISCOUNTED_BUSINESS:
      return {
        ...state,
        discountedBusinesses: action.payload.discountedBusinesses,
      };
    **case ReducerTypes.LIST_SERVICE_TRANSACTIONS:
      return {
        ...state,
        ListServiceTransactions: action.payload,
      };**
    case ReducerTypes.FAQ_LIST:
      return { ...state, faqList: action.payload.faqList };
    default:
      return state;
  }
}
export default appReducer;

I just need to put the binaries together and handle the rest of the work myself

Upvotes: 0

Views: 691

Answers (1)

Yasser hennawi
Yasser hennawi

Reputation: 815

I think what you need to do is to merge the old state together with the new one in the reducer, I am not exactly sure which key you mean, but I assume ListServiceTransactions, if that's the case, then in your reducer file, it should be:

    **case ReducerTypes.LIST_SERVICE_TRANSACTIONS:
      return {
        ...state,
        // Combining previous state with the new one
        ListServiceTransactions: [
          ...state.ListServiceTransactions,
          ...action.payload
        ],
      };**

Upvotes: 2

Related Questions