Reputation: 269
I am trying to achieve infinite scrolling in my react js project, I tried react-infinite-scroll-component package, but it did not work for me. So now I am trying useref here but it is also not working. I am trying to change the state page
while scrolling hits the bottom of the table, and then that state page
will be sent to api endpoint which will return more data. But it is not working for me. Here is my code:
// ref -----------------------
const tableWrapperRef = useRef(null);
const handleScroll = () => {
const wrapper = tableWrapperRef.current;
if (wrapper) {
const isScrolledToBottom =
wrapper.scrollHeight - wrapper.scrollTop === wrapper.clientHeight;
if (isScrolledToBottom) {
setPage((prev) => prev + 1);
}
}
};
useEffect(() => {
const wrapper = tableWrapperRef.current;
if (wrapper) {
wrapper.addEventListener("scroll", handleScroll);
}
return () => {
if (wrapper) {
wrapper.removeEventListener("scroll", handleScroll);
}
};
}, []);
// api calling
useEffect(() => {
if (debouncedSearchQuery.trim() === "") {
// If the search query is empty, fetch all items
axios
.get(
`${
import.meta.env.VITE_APP_API_BASE_URL
}/api/transaction/account-transactions/${
userInformation._id
}/${page}/15`,
{
headers: apiHeaders,
}
)
.then((res) => {
const decrypted = decryptData(res.data.data);
setUserTransactions(decrypted.transactionList);
console.log("all", decrypted.transactionList);
})
.catch((err) => {
const decrypted = decryptData(err.response.data.data);
if (decrypted.status === false) {
}
});
} else {
// If there is a search query, make the API call with the search query
axios
.get(
`${
import.meta.env.VITE_APP_API_BASE_URL
}/api/transaction/search-account-transactions/${
userInformation?._id
}/${page}/20/${debouncedSearchQuery}`,
{
headers: apiHeaders,
}
)
.then((res) => {
const decrypted = decryptData(res.data.data);
setUserTransactions(decrypted.transactionList);
console.log("search_results", decrypted.transactionList);
})
.catch((err) => {
const decrypted = decryptData(err.response.data.data);
if (decrypted?.status === false) {
setUserTransactions([]);
}
console.log(decrypted, "decrypted");
});
}
}, [page, debouncedSearchQuery, userInformation]);
<Card noborder>
<div className="md:flex justify-between items-center mb-6">
<div className=" flex gap-2 items-center">
<h4 className="card-title">{t("All transactions")}</h4>
<div
className=" flex items-center rounded-[10px] bg-[#FFF] pt-[0.7rem] pb-[0.7rem] pl-2"
style={{
boxShadow: "0px 4.32752px 35.70205px 0px rgba(0, 0, 0, 0.06) ",
// padding: "0 1rem",
}}
>
<span className=" text-3xl text-slate-900 cursor-pointer hover:text-slate-600">
<Icon icon="ic:twotone-search" />
</span>
<input
placeholder={"Search" + "..."}
value={searchQuery}
onChange={handleSearchChange}
className=" "
style={{ border: "none", outline: "none" }}
/>
</div>
</div>
<div className="date-range-custom2 relative">
<Datepicker
inputClassName="input-class"
containerClassName="container-class"
value={date}
onChange={handleValueChange}
showShortcuts={true}
primaryColor={"blue"}
/>
</div>
</div>
<div
className="overflow-x-auto -mx-6"
ref={tableWrapperRef} //calling ref here
>
<div className="max-h-[400px] overflow-y-auto custom-scrollbar">
<div className="inline-block min-w-full align-middle">
<table className="min-w-full divide-y divide-slate-100 table-fixed dark:divide-slate-700">
<thead className="bg-slate-200 dark:bg-slate-700 sticky top-0">
<tr className="">
<th className="table-th " scope="col">
{" "}
#
</th>
<th className="table-th " scope="col">
{" "}
Date & Time
</th>
<th className="table-th text-left" scope="col">
{" "}
Transaction ID
</th>
<th className="table-th text-left" scope="col">
{" "}
Payment Type
</th>
<th className="table-th text-left" scope="col">
{" "}
Name
</th>
<th className="table-th text-left" scope="col">
{" "}
Type
</th>
<th className="table-th text-left" scope="col">
{" "}
Amount
</th>
<th className="table-th text-left" scope="col">
{" "}
Status
</th>
</tr>
</thead>
<tbody className="bg-white divide-y divide-slate-100 dark:bg-slate-800 dark:divide-slate-700">
{userTransactions?.length > 0 && (
<>
{userTransactions?.map((transaction, index) => (
<tr
key={transaction._id}
className="text-slate-800 font-semibold"
>
<td className="table-td text-slate-500 font-normal">
{index + 1}
</td>
<td className="table-td text-slate-500 font-normal">
{new Date(transaction.createdAt).toLocaleString()}
</td>
<td className="table-td text-slate-500 font-normal">
{transaction.reference_id}
</td>
<td className="table-td text-slate-500 font-normal">
{transaction.service_type === "wallet_to_wallet"
? "Wallet to Wallet"
: transaction.service_type === "deposite_by_admin"
? "Deposited by Admin"
: transaction.service_type === "withdraw_by_admin"
? "Withdrawed by Admin"
: transaction.service_type}
</td>
<td className="table-td text-slate-500 font-normal">
{transaction.account.user.first_name}{" "}
{transaction.account.user.last_name}
</td>
<td className="table-td text-slate-500 font-normal">
{transaction.type}
</td>
<td className="table-td text-slate-500 font-normal">
{transaction?.currency?.symbol}
{transaction.amount.toFixed(2)}
</td>
<td className="table-td text-slate-500 font-normal">
<span
className={`${
transaction.status === "completed"
? "text-success-500 bg-success-500"
: "text-danger-500 bg-danger-500"
} inline-block px-3 min-w-[90px] text-center mx-auto py-1 rounded-[999px] bg-opacity-25 `}
>
{transaction.status}
</span>
</td>
</tr>
))}
</>
)}
</tbody>
</table>
{loading && (
<div className="w-full flex justify-center items-center min-h-[10vh]">
<h6>Loading...</h6>
</div>
)}
{userTransactions?.length === 0 && (
<div className=" w-full flex justify-center items-center min-h-[10vh]">
<h6>No transactions found</h6>
</div>
)}
</div>
</div>
</div>
</Card>
Upvotes: 1
Views: 272