KevinVandy / material-react-table

A fully featured Material UI V5 implementation of TanStack React Table V8, written from the ground up in TypeScript
https://material-react-table.com
MIT License
1.52k stars 439 forks source link

Manual pagination onPaginationChange triggers twice, resetting pageIndex to zero #1251

Open ponbac opened 1 month ago

ponbac commented 1 month ago

material-react-table version

3.0.1

react & react-dom versions

18.3.1

Describe the bug and the steps to reproduce it

Described by someone on StackOverflow here: https://stackoverflow.com/questions/79003280/material-react-table-pagination-not-working-as-expected-manual-pagination-unwant

Setting the same pagination state in initialState fixes the problem for me. It feels like the table instance gets recreated when it shouldn't? Sorry if the problem is on my part.

Minimal, Reproducible Example - (Optional, but Recommended)

From the StackOverflow post, my code is similar:

const UsersComponents = ({ showCreateUser, setShowCreateUser }) => {
  const theme = useTheme();
  const [validationErrors, setValidationErrors] = useState({});

  const [tableData, setTableData] = useState([]);
  const [pagination, setPagination] = useState({
    pageIndex: 0,
    pageSize: 10,
  });

  const handlePaginationChange = (updater) => {
    setPagination((oldPagination) => {
      const newPagination =
        typeof updater === "function" ? updater(oldPagination) : updater;

      console.log("Updated pagination:", newPagination); // Debug the new pagination state
      return newPagination;
    });
  };

  const queryClient = useQueryClient();

  const {
    data: fetchedUsers = [],
    isError: isLoadingUsersError,
    isFetching: isFetchingUsers,
    refetch,
  } = useQuery({
    queryKey: ["users", pagination.pageIndex, pagination.pageSize],
    refetchOnWindowFocus: false,
    placeholderData: keepPreviousData,
    queryFn: async () => {
      const response = await fetchUsers({
        offset: pagination.pageIndex * pagination.pageSize,
        limit: pagination.pageSize,
      });
      console.log(response, "response chk");
      return response;
    },
  });

  const { data: userCount = 0 } = useQuery({
    queryKey: ["totalCount"],
    queryFn: fetchUserCount,
    refetchOnWindowFocus: false,
  });

  const tableColumns = useMemo(
    () => columns(validationErrors, setValidationErrors),
    [validationErrors]
  );

  const table = useMaterialReactTable({
    columns: tableColumns,
    data: fetchedUsers,
    pageCount: Math.ceil(userCount / pagination.pageSize),
    onPaginationChange: handlePaginationChange,
    pagination,
    muiPaginationProps: {
      color: "primary",
      shape: "rounded",
      showRowsPerPage: false,
      variant: "outlined",
    },
    mrtTheme: (theme) => ({
      baseBackgroundColor: theme.palette.background.paper,
    }),
    manualPagination: true,
    createDisplayMode: "modal", //default ('row', and 'custom' are also available)
    editDisplayMode: "row", //default ('row', 'cell', 'table', and 'custom' are also available)
    enableEditing: true,
    paginationDisplayMode: "pages",
    paginateExpandedRows: true,
    enableRowSelection: true,
    enableFullScreenToggle: false,
    enableDensityToggle: false,
    columnFilterDisplayMode: "popover",
    positionToolbarAlertBanner: "bottom",
    positionGlobalFilter: "left",
    getRowId: (row) => row.id,
    muiSearchTextFieldProps: {
      placeholder: "Search all users",
      variant: "outlined",
    },
    muiToolbarAlertBannerProps: isLoadingUsersError
      ? {
          color: "error",
          children: "Error loading data",
        }
      : undefined,
    muiTableContainerProps: {
      sx: {
        minHeight: "500px",
      },
    },

    state: {
      pagination,
      isLoading: isFetchingUsers,
      isSaving: isCreatingUser || isUpdatingUser || isDeletingUser,
      showAlertBanner: isLoadingUsersError,
      showProgressBars: isFetchingUsers,
    },
  });

  return (
    <>
      <MaterialReactTable table={table} />
    </>
  );
};

const queryClient = new QueryClient();

const UserManagement = ({ showCreateUser, setShowCreateUser }) => (
  <QueryClientProvider client={queryClient}>
    <UsersComponents
      showCreateUser={showCreateUser}
      setShowCreateUser={setShowCreateUser}
    />
  </QueryClientProvider>
);

export default UserManagement;

Screenshots or Videos (Optional)

No response

Do you intend to try to help solve this bug with your own PR?

None

Terms

Zemelia commented 3 days ago

Hi, same issue on my side as well...