my mind is almost expoilt, can´t make a initial state of rows selection with table react table. Try to put initial state by "rowSelection", works fine when i put a string like this: [true, false, true, false]. But when i'm trying to get asyncronily this data it doesn´t work, and first value taken when render is a enmpy string for "initialSelectedRowIds()", because el estado "data" is too a empy string at first render. How can i make it corretly??, please help me.
import * as React from 'react'
import {
useState,
useReducer,
useMemo,
useRef,
useEffect,
useContext
} from 'react'
import {
Column,
ColumnDef,
createColumnHelper,
flexRender,
getCoreRowModel,
getFilteredRowModel,
getPaginationRowModel,
Table,
useReactTable,
} from '@tanstack/react-table'
import {AdminContext} from "../context/AdminContext.js";
import AppContext from "../context/AppContext";
import "../styles/ModalUsersSector.scss"
function TableManyToMany(props){
const [token] = useContext(AdminContext);
const [data, setData] = useState([])
const rerender = useReducer(() => ({}), {})[1]
/* API connector to get data users of sector*/
useEffect(() => {
const makeData = async () => {
const requestOptions = {
method: "GET",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer " + token,
},
};
const response = await fetch(`/api/sector_users/${props.id}`, requestOptions);
if(!response.ok){
console.log('error')
}else{
const users = await response.json();
setData(users)
}
}
makeData()
}, [])
// Make columns
const columns = useMemo(() => [
{
id: 'select',
header: ({ table }) => (
<IndeterminateCheckbox
{...{
checked: table.getIsAllRowsSelected(),
indeterminate: table.getIsSomeRowsSelected(),
onChange: table.getToggleAllRowsSelectedHandler(),
}}
/>
),
cell: ({ row }) => (
<div className="px-1">
<IndeterminateCheckbox
{...{
checked: row.getIsSelected(),
disabled: !row.getCanSelect(),
indeterminate: row.getIsSomeSelected(),
onChange: row.getToggleSelectedHandler(),
}}
/>
</div>
),
},
{
accessorKey: 'users_name',
header: 'Nombre',
footer: props => props.column.id,
},
{
accessorKey: 'users_role',
header: 'Puesto',
footer: props => props.column.id,
},
{
accessorKey: 'users_department',
header: 'Centro',
footer: props => props.column.id,
},
{
accessorKey: 'users_center',
header: 'Gerencia',
footer: props => props.column.id,
},
], [])
//Make Checkbox
function IndeterminateCheckbox({
indeterminate,
className = '',
...rest
}) {
const ref = useRef()
useEffect(() => {
if (typeof indeterminate === 'boolean') {
ref.current.indeterminate = !rest.checked && indeterminate
}
}, [ref, indeterminate])
return (
<input
type="checkbox"
ref={ref}
className={className + ' cursor-pointer'}
{...rest}
/>
)
}
/* For get initial selected users for the sector*/
const initialSelectedRowIds = () => {
let initialList=[]
for (let i = 0; i < data.length; i++) {
let user = data[i];
let matchingSector = user.sectors.some(sector => sector.id === props.id);
if (matchingSector) {
initialList.push(true)
}else{
initialList.push(false)
}
}
return initialList
}
//Make table
const table = useReactTable({
data,
columns,
getCoreRowModel: getCoreRowModel(),
initialState: {
rowSelection: initialSelectedRowIds(),
}
})
return (
<div>
<table className="styled-table-user" >
<thead>
{table.getHeaderGroups().map(headerGroup => (
<tr key={headerGroup.id}>
{headerGroup.headers.map(header => (
<th key={header.id}>
{header.isPlaceholder
? null
: flexRender(
header.column.columnDef.header,
header.getContext()
)}
</th>
))}
</tr>
))}
</thead>
<tbody>
{table.getRowModel().rows.map(row => (
<tr key={row.id}>
{row.getVisibleCells().map(cell => (
<td key={cell.id}>
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</td>
))}
</tr>
))}
</tbody>
</table>
</div>
)
}
export default TableManyToMany
One more thing, the data is rendering fine in table. I whondering why "data" is empy when i'm trying put initial rows selected. I tried to use useMemo for put initial rows selected, it didn't work too.