I have a page with a Table, this table is controlled with other inputs which are put in common through a custom hook, I try to read the values in the hook in the page where the component is but although the values inside the hook are updated they are not read in the page
to clarify
[Page] - contains -> [ table ] - controlled by [inputs in page]
// Due to a complex state, the state of the hook is controlled by a reducer
this is a smaller version of codesandbox reproducing the issue. https://codesandbox.io/p/sandbox/charming-lumiere-vyoewu?file=%2Fsrc%2Freducers%2FpageQueryReducer.ts&selection=%5B%7B%22endColumn%22%3A3%2C%22endLineNumber%22%3A67%2C%22startColumn%22%3A3%2C%22startLineNumber%22%3A67%7D%5D
// Hook
import {
PageQueryActionKind,
pageQueryReducer,
queryInit,
} from "../reducers/pageQueryReducer";
import { useEffect, useReducer } from "react";
const useTable = () => {
const [state, dispatch] = useReducer(pageQueryReducer, queryInit);
useEffect(() => {
console.log("state read by the hook", state);
}, [state]);
const handlePageChange = (page: number) => {
dispatch({
type: PageQueryActionKind.SET_PAGE,
payload: {
page,
per_page: state.perPage,
},
});
};
const handlePerPageChange = (perPage: number) => {
dispatch({
type: PageQueryActionKind.SET_PAGE,
payload: { page: state.page, per_page: perPage },
});
};
const handleSortChange = (column: string, direction: "asc" | "desc" | "") => {
dispatch({
type: PageQueryActionKind.SET_COL_SORT,
payload: {
columnSortItem: column,
columnOrder: direction,
},
});
};
return {
currentPage: state.page,
setCurrentPage: handlePageChange,
entriesPerPage: state.perPage,
setEntriesPerPage: handlePerPageChange,
columnSortDirection: state.columnOrder,
currentSortedColumn: state.columnSortItem,
setColumnSort: handleSortChange,
tableFilters: state.tableFilters,
queryString: state.queryString,
overAllState: state,
};
};
export default useTable;
// Components
const Checkbox = ({ label, onChangeFunc }) => {
return (
<div className="checkbox-wrapper">
<label>
<input type="checkbox" onChange={onChangeFunc} />
<span>{label}</span>
</label>
</div>
);
};
export default Checkbox;
import Checkbox from "./checkbox";
import useTable from "../hooks/useTable";
const Table = () => {
const { setColumnSort } = useTable();
return (
<div>
Test quote and quote table
<Checkbox
label="test"
onChangeFunc={() => setColumnSort("hipothethicalColumn", "asc")}
/>
</div>
);
};
export default Table;
// Reducer
type TableFilters = {
col: string;
order: string;
};
interface State {
page: number;
perPage: number;
tableFilters: TableFilters[];
columnSortItem: string;
columnOrder: "asc" | "desc" | "";
queryString: string;
}
export enum PageQueryActionKind {
SET_PAGE = "set_page",
SET_COL_SORT = "set_col_sort",
SET_FILTER = "set_filter",
SET_ROWS_PER_PAGE = "set_rows_per_page",
RESET = "reset",
}
interface SetPageAction {
type: PageQueryActionKind.SET_PAGE;
payload: {
page: number;
per_page: number;
};
}
interface SetColSortAction {
type: PageQueryActionKind.SET_COL_SORT;
payload: {
columnSortItem: string;
columnOrder: "asc" | "desc" | "";
};
}
interface SetFilterAction {
type: PageQueryActionKind.SET_FILTER;
payload: {
filter: string;
value: string;
};
}
interface SetRowsPerPageAction {
type: PageQueryActionKind.SET_ROWS_PER_PAGE;
payload: number;
}
type Actions =
| SetPageAction
| SetColSortAction
| SetFilterAction
| SetRowsPerPageAction
| { type: PageQueryActionKind.RESET; payload: undefined };
export const queryInit = {
page: 1,
perPage: 25,
tableFilters: [],
columnSortItem: "intervention_code",
columnOrder: "desc",
queryString:
"/afm_interventions?company_id=1&page=1&per_page=25&order_by=intervention_code&order=desc",
};
export const pageQueryReducer = (state: State, action: Actions): State => {
console.log("reducer prev values and action", { action, state });
switch (action.type) {
case PageQueryActionKind.SET_PAGE:
return {
...state,
page: action.payload.page,
perPage: action.payload.per_page,
queryString: state.queryString.replace(
/page=[0-9]+&per_page=[0-9]+/,
`page=${action.payload.page}&per_page=${action.payload.per_page}`
),
};
case PageQueryActionKind.SET_COL_SORT:
return {
...state,
columnSortItem: action.payload.columnSortItem,
columnOrder: action.payload.columnOrder,
queryString: state.queryString.replace(
/order_by=[a-z_]+&order=[a-z]+/,
`order_by=${action.payload.columnSortItem}&order=${action.payload.columnOrder}`
),
};
case PageQueryActionKind.SET_FILTER:
if (
state.tableFilters.find(
(tableFilter) => tableFilter.col === action.payload.filter
)
) {
return {
...state,
tableFilters: state.tableFilters.map((tableFilter) => {
if (tableFilter.col === action.payload.filter) {
return {
...tableFilter,
order: action.payload.value,
};
}
return tableFilter;
}),
};
}
return {
...state,
tableFilters: [
...state.tableFilters,
{ col: action.payload.filter, order: action.payload.value },
],
};
case PageQueryActionKind.SET_ROWS_PER_PAGE:
return {
...state,
perPage: action.payload,
};
case PageQueryActionKind.RESET:
return queryInit;
default:
return state;
}
};