'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 |
|---|
