-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathuseDataTable.jsx
More file actions
82 lines (72 loc) · 2.43 KB
/
useDataTable.jsx
File metadata and controls
82 lines (72 loc) · 2.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import React from "react";
import useAxios from "axios-hooks";
import LoadingBoundary from "../containers/LoadingBoundary";
import DataTable from "./DataTable";
import useQueryParamsTable from "./useQueryParamsTable";
const defualtPageParams = {
page_size: 10,
page: 1,
};
const defaultModifier = (responseData) => responseData?.results || [];
/**
* Suitable for fetching data from a server. Thus, pagination/filtering/sorting in most cases should be handled by the server too.
* @param url URL to use to make the request.
* @param params Query parameters that will be added to the request, which can be overridden by table filters.
* @param toPassTableProps Table properties (ex. columns, config, initialState, SubComponent) that will be used for creating the table component.
* @param modifier Function that defines in which field of the response the data that will be used is located.
*/
function useDataTable(
{ url, params: defaultParams, },
toPassTableProps,
modifier = defaultModifier
) {
// hook
const [params, tableInitialState, tableStateReducer] = useQueryParamsTable();
// state
const [initialLoading, setInitialLoading] = React.useState(true);
// API
const [{ data, loading, error, }, refetch] = useAxios({
url,
params: { ...defualtPageParams, ...defaultParams, ...params, },
});
// side-effects
// initial table loading (spinner)
React.useEffect(() => {
if (!loading) setInitialLoading(false);
}, [loading]);
// https://it.reactjs.org/docs/hooks-effect.html#tip-optimizing-performance-by-skipping-effects
// https://it.reactjs.org/docs/hooks-reference.html#usememo
const tableNode = React.useMemo(
() => (
<LoadingBoundary
loading={initialLoading}
error={error}
render={() => (
<DataTable
data={data ? modifier(data) : []}
pageCount={data?.total_pages || 1}
stateReducer={tableStateReducer}
initialState={tableInitialState}
manualPagination
manualFilters
manualSortBy
customProps={{ refetchTableData: refetch, }}
{...toPassTableProps}
/>
)}
/>
),
[
data,
modifier,
initialLoading,
error,
tableInitialState,
tableStateReducer,
refetch,
toPassTableProps,
]
);
return [data, tableNode, refetch, tableStateReducer, loading, tableInitialState];
}
export default useDataTable;