'External paginator changes page after two clicks instead of one

I am trying to implement two pagination menus in React using an external library, it works however currently to change a page to the second one you have to click two times instead of one and I cant figure out why.

I consoled logged the skip and take values and they are present, why does the pagination behave like that how can I make the two pagination components work simultaneously with clicking once? Here is my code:

import React, { useEffect, useRef, useState } from 'react';
import ReactDOM from 'react-dom';

import {
  Grid,
  GridColumn as Column,
  GridToolbar,
} from '@progress/kendo-react-grid';
import { products } from './products';
import { Popup } from '@progress/kendo-react-popup';
import { process } from '@progress/kendo-data-query';
import { Pager } from '@progress/kendo-react-data-tools';

import '@progress/kendo-theme-default/dist/all.css';
import './styles.css';

let loadedColumns = localStorage.getItem('gridColumns');
let defaultColumns = [
  {
    title: 'Product Id',
    field: 'ProductID',
    show: true,
  },
  {
    title: 'Product Name',
    field: 'ProductName',
    show: true,
  },
  {
    title: 'Quantity Per Unit',
    field: 'QuantityPerUnit',
    show: true,
  },
  {
    title: 'Unit Price',
    field: 'UnitPrice',
    show: true,
  },
  {
    title: 'Units In Stock',
    field: 'UnitsInStock',
    show: true,
  },
];
console.log(loadedColumns);
const GridColumns = loadedColumns ? JSON.parse(loadedColumns) : defaultColumns;

const App = () => {
  //GRID HIDE/SHOW POPUP MENU
  const anchor = useRef();
  const gridRef = useRef();
  const [show, setShow] = useState(false);
  const onClick = () => {
    setShow(!show);
  };

  //GRID DATA SETTING
  const createDataState = (dataState) => {
    return {
      result: process(products.slice(0), dataState),
      dataState: dataState,
    };
  };
  let initialState = createDataState({
    take: 5,
    skip: 0,
  });

  const [result, setResult] = useState(initialState.result);
  const [dataState, setDataState] = useState(initialState.dataState);
  const [stateColumns, setStateColumns] = useState(GridColumns);

  const dataStateChange = (event) => {
    let updatedState = createDataState(event.dataState);
    setResult(updatedState.result);
    setDataState(updatedState.dataState);
  };

  //GRID REORDER/RESIZE INIT SETTING
  const onColumnReorder = (props) => {
    setStateColumns(addHiddenColumns(props.columns));
  };

  const onColumnResize = (props) => {
    setStateColumns(addHiddenColumns(props.columns));
  };

  const addHiddenColumns = (columns) => {
    let newColumnsState = defaultColumns.map((col) => {
      let _col = columns.filter((c) => c.field == col.field);
      if (_col.length > 0) {
        return {
          ...col,
          orderIndex: _col[0].orderIndex ? _col[0].orderIndex : -1,
          width: _col[0].width ? _col[0].width : '',
        };
      } else {
        return { ...col, show: false };
      }
    });
    return newColumnsState;
  };

  const handlePageChange = (event) => {
    const { skip, take } = event;
    setDataState({ ...dataState, skip: skip, take: take });
    setResult(process(products, dataState));
    console.log(`Page Change: skip ${skip}, take ${take}`);
  };

  const saveColumnsState = (columns) => {
    let currentColumnsState = JSON.stringify(columns);
    localStorage.setItem('gridColumns', currentColumnsState);
  };

  const [oneVisibleColumn, setOneVisibleColumn] = useState(false);

  let toggleColumn = (id) => {
    let visibleSolumnsCount = 0;
    for (let i = 0; i < stateColumns.length; i++) {
      if (stateColumns[i].show === true) {
        visibleSolumnsCount++;
      }
    }
    if (visibleSolumnsCount === 2 && stateColumns[id].show === true) {
      setOneVisibleColumn(true);
    } else {
      setOneVisibleColumn(false);
    }

    setStateColumns(
      stateColumns.map((column, idx) =>
        idx === id ? { ...column, show: !column.show } : column
      )
    );
  };

  useEffect(() => {
    saveColumnsState(stateColumns);
  }, [stateColumns]);

  return (
    <div>
      <Popup anchor={anchor.current} show={show} popupClass={'popup-content'}>
        <div>
          {stateColumns.map((column, idx) => (
            <div key={idx}>
              <span style={{ padding: '0.5rem' }}>
                <input
                  id={idx}
                  disabled={column.show && oneVisibleColumn}
                  type="checkbox"
                  className="k-checkbox k-checkbox-md k-rounded-md"
                  readOnly={true}
                  checked={column.show}
                  onChange={() => {
                    toggleColumn(idx);
                  }}
                />
                <label
                  style={{ marginLeft: '0.5rem' }}
                  htmlFor={idx}
                  className="k-checkbox-label"
                >
                  {column.title}
                </label>
              </span>
            </div>
          ))}
        </div>
      </Popup>

      <Grid
        style={{ width: '100%' }}
        data={result}
        {...dataState}
        onDataStateChange={dataStateChange}
        resizable={true}
        reorderable={true}
        //
        ref={gridRef.current}
        onColumnReorder={onColumnReorder}
        onColumnResize={onColumnResize}
        //total={data.length}
        pageable={{
          pageSize: true,
          pageSizes: [5, 10, 15],
        }}
      >
        <GridToolbar>
          <Pager
            skip={dataState.skip}
            take={dataState.take}
            total={products.length}
            info={true}
            type="numeric"
            pageSizes={[5, 10, 15]}
            responsive={true}
            previousNext={true}
            onPageChange={handlePageChange}
            style={{ border: 'none', width: '100%' }}
          />
        </GridToolbar>
        <GridToolbar>
          <button
            title="Click"
            className="k-button k-button-md k-rounded-md k-button-solid k-button-solid-primary "
            onClick={onClick}
            style={{ backgroundColor: 'teal', color: 'white' }}
            ref={anchor}
          >
            {show ? 'Hide column menu' : 'Show column menu'}
          </button>
        </GridToolbar>
        {stateColumns.map(
          (column, idx) =>
            column.show && (
              <Column
                key={idx}
                field={column.field}
                title={column.title}
                {...column}
              />
            )
        )}
      </Grid>
    </div>
  );
};

ReactDOM.render(<App />, document.getElementById('root'));

And here is a runnable example that reproduces the problem:

https://stackblitz.com/edit/react-grid-toggle-column-bqfjxu?file=index.js



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source