React Table Trigger Changed Without SWR
The Back Story about this Metaphor
React Table Trigger Changed Without SWR
Metaphore story
I'm into the world of javascript and reactjs is absolutely nil! And I found react-table
from TanStack and it's really cool! That agnostic (What The Buff!)
And I'm trying to simplify my old way of working with jQuery
when I was almost sinking to the bottom of the ocean (Hypertext Preprocessor) and didn't find the light of JavaScript
as a complete combat tool more promising.
In jQuery I need to create a function to repeat the request and I trigger it from the targeted event and it's easy.
My question is how can I do the same thing but in react-table
by not using any other library.
And here's what happened:
1// file: components/TablePagination.js 2function TablePagination({ 3 columns, 4 data, 5 fetchData, 6 loading, 7 pageCount: controlledPageCount, 8 totalRow, 9 actions: Actions, 10}) { 11 const { 12 getTableProps, 13 getTableBodyProps, 14 headerGroups, 15 prepareRow, 16 page, 17 canPreviousPage, 18 canNextPage, 19 pageOptions, 20 pageCount, 21 gotoPage, 22 nextPage, 23 previousPage, 24 setPageSize, 25 state: { pageIndex, pageSize, globalFilter, sortBy }, 26 preGlobalFilteredRows, 27 setGlobalFilter, 28 } = useTable( 29 { 30 columns, 31 data, 32 manualPagination: true, 33 manualGlobalFilter: true, 34 manualSortBy: true, 35 initialState: { 36 pageIndex: 0, 37 pageSize: 10, 38 }, // Pass our hoisted table state 39 pageCount: controlledPageCount, 40 autoResetSortBy: false, 41 autoResetExpanded: false, 42 autoResetPage: false, 43 }, 44 useGlobalFilter, 45 useSortBy, 46 usePagination 47 ); 48 49 const GlobalFilter = ({ 50 preGlobalFilteredRows, 51 globalFilter, 52 setGlobalFilter, 53 }) => { 54 const count = preGlobalFilteredRows; 55 const [value, setValue] = React.useState(globalFilter); 56 const onChange = useAsyncDebounce((value) => { 57 setGlobalFilter(value || undefined); 58 }, 700); 59 60 return ( 61 <div 62 className={ 63 Actions !== undefined 64 ? 'flex flex-row justify-between' 65 : 'flex flex-col' 66 } 67 > 68 {Actions !== undefined ? <Actions /> : null} 69 <input 70 value={value || ''} 71 onChange={(e) => { 72 setValue(e.target.value); 73 onChange(e.target.value); 74 }} 75 placeholder={`${count} records...`} 76 type="search" 77 className={`input input-bordered input-sm w-full max-w-xs focus:outline-0 mb-2 ${ 78 Actions !== undefined ? '' : 'self-end' 79 }`} 80 /> 81 </div> 82 ); 83 }; 84 85 React.useEffect(() => { 86 let search = globalFilter === undefined ? '' : globalFilter; 87 fetchData(pageSize, pageIndex, search); 88 }, [fetchData, pageIndex, pageSize, globalFilter, sortBy]); 89 90 return ( 91 <> 92 <GlobalFilter 93 preGlobalFilteredRows={totalRow} 94 globalFilter={globalFilter} 95 setGlobalFilter={setGlobalFilter} 96 /> 97 <div className="overflow-x-auto"> 98 <table 99 {...getTableProps()} 100 className="table table-compact table-zebra w-full" 101 > 102 <thead> 103 {headerGroups.map((headerGroup) => ( 104 <tr {...headerGroup.getHeaderGroupProps()}> 105 {headerGroup.headers.map((column) => ( 106 <th {...column.getHeaderProps(column.getSortByToggleProps())}> 107 <span> 108 {column.isSorted ? ( 109 column.isSortedDesc ? ( 110 <ArrowLongDownIcon className="h-4 w-4 inline mr-1" /> 111 ) : ( 112 <ArrowLongUpIcon className="h-4 w-4 inline mr-1" /> 113 ) 114 ) : ( 115 <FunnelIcon className="h-4 w-4 inline mr-1" /> 116 )} 117 </span> 118 {column.render('Header')} 119 </th> 120 ))} 121 </tr> 122 ))} 123 </thead> 124 <tbody {...getTableBodyProps()}> 125 {page.length > 0 ? ( 126 page.map((row, i) => { 127 prepareRow(row); 128 return ( 129 <tr {...row.getRowProps()} className="hover"> 130 {row.cells.map((cell) => { 131 return ( 132 <td {...cell.getCellProps()}>{cell.render('Cell')}</td> 133 ); 134 })} 135 </tr> 136 ); 137 }) 138 ) : ( 139 <tr className="hover"> 140 <td colSpan={10000} className="text-center"> 141 Data not found! 142 </td> 143 </tr> 144 )} 145 {loading ? ( 146 <tr> 147 <td colSpan="10000">Loading...</td> 148 </tr> 149 ) : null} 150 </tbody> 151 </table> 152 </div> 153 <div className="flex flex-row justify-between"> 154 <div className="mt-2"> 155 <span> 156 Halaman{' '} 157 <strong> 158 {pageIndex + 1} dari {pageOptions.length} 159 </strong>{' '} 160 Total <strong>{preGlobalFilteredRows.length}</strong>{' '} 161 </span> 162 <span> 163 | Lompat ke halaman:{' '} 164 <input 165 type="number" 166 defaultValue={pageIndex + 1} 167 onChange={(e) => { 168 const page = e.target.value ? Number(e.target.value) - 1 : 0; 169 gotoPage(page); 170 }} 171 className="input input-bordered input-sm w-20 max-w-xs focus:outline-0" 172 /> 173 </span> <select 174 value={pageSize} 175 onChange={(e) => { 176 setPageSize(Number(e.target.value)); 177 }} 178 className="select select-bordered select-sm w-30 max-w-xs focus:outline-0" 179 > 180 {[10, 20, 30, 40, 50].map((pageSize) => ( 181 <option key={pageSize} value={pageSize}> 182 Tampilkan {pageSize} baris 183 </option> 184 ))} 185 </select> 186 </div> 187 <div className="mt-2"> 188 <button 189 className="btn btn-xs" 190 onClick={() => gotoPage(0)} 191 disabled={!canPreviousPage} 192 > 193 {'<<'} 194 </button>{' '} 195 <button 196 className="btn btn-xs" 197 onClick={() => previousPage()} 198 disabled={!canPreviousPage} 199 > 200 {'<'} 201 </button>{' '} 202 <button 203 className="btn btn-xs" 204 onClick={() => nextPage()} 205 disabled={!canNextPage} 206 > 207 {'>'} 208 </button>{' '} 209 <button 210 className="btn btn-xs" 211 onClick={() => gotoPage(pageCount - 1)} 212 disabled={!canNextPage} 213 > 214 {'>>'} 215 </button>{' '} 216 </div> 217 </div> 218 </> 219 ); 220} 221 222export default TablePagination;
What I really want is that when I update data from a modal component (child), I can trigger the previous component (parent) I have to refresh the data in the table after a data change.
1// file: pages/Example.js (parent) 2function Example() { 3 4 const [data, setData] = useState([]); 5 const [loading, setLoading] = useState(false) 6 const [pageCount, setPageCount] = useState(0) 7 const [totalRow, setTotalRow] = useState(0) 8 const [refresh, setRefresh] = useState(false) 9 10 const fetchData = useCallback(async (pageSize, pageIndex, search) => { 11 setLoading(true) 12 const queryOptions = { 13 page: pageIndex, 14 limit: pageSize, 15 search: search 16 } 17 const customers = await customerDatatable(queryOptions) 18 19 setData(customers.data) 20 setPageCount(customers.pagination.totalPage) 21 setTotalRow(customers.pagination.totalRow) 22 setLoading(false) 23 setRefresh(false) 24 }, [refresh]); 25 26 const columns = useMemo( 27 () => [ 28 ...., 29 { 30 Header: 'Actions', 31 accessor: (row) => { 32 return ( 33 <div className='flex flex-row w-38'> 34 <ReuseableModal modalId={`modalEdit-${row.customer_uuid}`} btnClassName={`btn-xs btn-info mr-2`} btnContent={<PencilSquareIcon className='h-3 w-3' />} width='w-11/12 max-w-5xl'> 35 // here the child 36 <FormEdit data={row} setRefresh={setRefresh} modalTarget={row.customer_uuid} /> 37 </ReuseableModal> 38 </div> 39 ) 40 }, 41 disableSortBy: true 42 } 43 ], 44 [] 45 ); 46 47 return ( 48 <Fragment> 49 <Helmet> 50 <title>Example</title> 51 </Helmet> 52 <section className='p-3'> 53 <div className="bg-base-300 p-3 rounded"> 54 <TablePagination 55 columns={columns} 56 data={data} 57 fetchData={fetchData} 58 loading={loading} 59 pageCount={pageCount} 60 totalRow={totalRow} 61 /> 62 </div> 63 </section> 64 </Fragment> 65 ) 66} 67 68export default PelangganAktif 69}
And here the modal popup
1// file: components/modal/FormEdit.js (child) 2function FormEdit({ data, setRefresh, modalTarget }) { 3 const { addToast } = useToast(); 4 const initValues = data; 5 6 const formSubmit = async (values) => { 7 const updated = await customerUpdate(values); 8 if (updated.type === 'success') { 9 addToast( 10 'success', 11 'top-right', 12 'Data updated!', 13 `${data.profiles.fullname} detail updated`, 14 5000 15 ); 16 document.getElementById(`modalEdit-${modalTarget}`).click(); 17 setRefresh(true); 18 resetForm(); 19 } else { 20 addToast( 21 'error', 22 'top-right', 23 'Data failed to update!', 24 `${data.profiles.fullname} defail failed to update`, 25 5000 26 ); 27 } 28 }; 29 30 const { values, errors, touched, handleChange, handleSubmit, resetForm } = 31 useFormik({ 32 initialValues: initValues, 33 onSubmit: formSubmit, 34 enableReinitialize: true, 35 }); 36 37 return; // your form here 38} 39 40export default FormEdit;
That's it!
A demo/repos link
No response