react-data-table-component icon indicating copy to clipboard operation
react-data-table-component copied to clipboard

onChangeRowsPerPage and onChangePage is calling on initial rendering

Open dbrahul opened this issue 1 year ago • 0 comments

Issue Checklist

  • [x] Agree to the Code of Conduct
  • [x] Read the README
  • [x] You are using React 16.8.0+
  • [ ] You installed styled-components
  • [x] Include relevant code or preferably a code sandbox

Describe the bug

on the initial rendering, the onChangeRowsPerPage and onChangePage are calling twice

current version "react": "^18.3.1", "react-data-table-component": "^7.6.2",

This is what I'm trying

import React, { useEffect, useState } from "react";
import DataTable from "react-data-table-component";
import { PlayerAPI, teamAPI } from "../config/axiosUtils";
import { columns } from "../Table/columns/playerColumn";
import TeamSearchFilter from "./filter/TableSearchFilter";
import useToken from "../services/useToken";
import { Link, useSearchParams } from "react-router-dom";

const PlayerTableData = () => {
  const token = useToken();
  const [data, setData] = useState([]);
  const [error, setError] = useState("");
  const [teams, setTeam] = useState([]);
  const [searchParams, setSearchParams] = useSearchParams();
  const searchParamsObject = Object.fromEntries([...searchParams]);
  const [query, setQuery] = useState({
    ...searchParamsObject,
  });
  const [filterText, setFilterText] = useState("");
  const [loading, setLoading] = useState(false);
  const [totalData, setTotalData] = useState(0);
  const [selectedTeam, setSelectedTeam] = useState("");

  const handleSearchChange = (e) => {
    const search = e.target.value;
    setFilterText(search);
    setQuery((prev) => {
      return { ...prev, page: 1, searchKey: search };
    });
  };

  useEffect(() => {
    async function fetchData() {
      try {
        setLoading(true);
        const encodedQuery = new URLSearchParams(query).toString();
        setSearchParams(encodedQuery);
        const response = await PlayerAPI.getAllPlayer(encodedQuery);
        setData(response.data.data.players);
        setTotalData(response.data.data.pagination.totalPlayers);
      } catch (error) {
        setError(error.message);
      } finally {
        setLoading(false);
      }
    }
    fetchData();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [query, token]);

  // Fetch all teams for the dropdown
  useEffect(() => {
    async function fetchData() {
      try {
        setError("");
        const response = await teamAPI.getAllTeams({ page: 1, limit: 12 });
        setTeam(response.data.data.team);
      } catch (error) {
        setError(error.message);
      }
    }
    fetchData();
  }, [token]);

  // Set team from query on first render
  useEffect(() => {
    if (searchParamsObject.id) {
      setSelectedTeam(searchParamsObject.id);
    }
    if (searchParamsObject.searchKey) {
      setFilterText(searchParamsObject.searchKey);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  // Handle team change
  const teamChage = (e) => {
    const selectedTeamId = e.target.value;
    setSelectedTeam(selectedTeamId); // Update dropdown value
    setQuery({ ...query, id: selectedTeamId, page: 1 });
  };

  const handleRowPerPage = (newPerPage, page) => {
    console.log("handleRowPerPage triggered:", { newPerPage, page }); // Prints the call stack
    setQuery({ ...query, limit: newPerPage, page: page });
  };

  // Remove player with the given ID
  const removePlayer = (playerId) => {
    setData((prevPlayer) =>
      prevPlayer.filter((player) => player.id !== playerId)
    );
    setTotalData(totalData - 1);
  };

  const SortingFunction = (selectedColumn, sortDirection) => {
    if (selectedColumn.id) {
      const sort = { sort: `${selectedColumn.sortField}:${sortDirection}` };
      setQuery((prev) => {
        return { ...prev, ...sort };
      });
    }
  };

  const pageChange = (page, totalRows) => {
    console.log(page, totalRows);
    if (page) {
      console.log("page Change", page, totalRows);
      setQuery({ ...query, page: page });
    }
  };

  console.log(query);

  if (error !== "" && loading === false) {
    return (
      <>
        <div className="text-center">{error}</div>
      </>
    );
  }

  return (
    <div>
      {/* Search Input */}
      <div className="mb-3 row justify-content-end">
        <div className="col-sm-3">
          <label className="col-form-label">Select Team</label>
          <select
            className="form-select"
            value={selectedTeam} // Controlled value
            onChange={teamChage}
          >
            <option value={""}>Choose team</option>
            {teams.map((team) => (
              <option value={team.id} key={team.id + team.created_at}>
                {team.team_name}
              </option>
            ))}
          </select>
        </div>
      </div>

      <TeamSearchFilter
        filterText={filterText}
        handleSearchChange={handleSearchChange}
        title={
          <Link to="/add-player" className="btn-theme">
            Add
          </Link>
        }
      />
      {/* DataTable Component */}
      <DataTable
        progressPending={loading}
        columns={columns(removePlayer)}
        data={data}
        highlightOnHover
        paginationPerPage={query.limit || 10}
        striped
        responsive
        pagination={true}
        paginationServer={true}
        paginationTotalRows={totalData}
        paginationDefaultPage={query.page || 1}
        onChangeRowsPerPage={(newPerPage, page) =>
          handleRowPerPage(newPerPage, page)
        }
        onChangePage={(page, totalRows) => pageChange(page, totalRows)}
        sortServer
        onSort={(selectedColumn, sortDirection) =>
          SortingFunction(selectedColumn, sortDirection)
        }
      />
    </div>
  );
};

export { PlayerTableData };

dbrahul avatar Nov 25 '24 17:11 dbrahul