Reputation: 79
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
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