Error with accessorFn on nested props with v2.12.0 onwards
ColinMorris83 opened this issue · 1 comments
material-react-table version
v2.13.1
react & react-dom versions
v18.3.1
Describe the bug and the steps to reproduce it
After going from v2.11.3 to any newer version, am getting an error during rendering of any table that has an accessorFn that uses nested props.
e.g.
accessorFn: (row) => `${row.IdentityInfo.LastName}, ${row.IdentityInfo.FirstName}`,
Will error in the console about trying to call LastName on undefined.
Have narrowed it down in the sandbox to the use of enableFacetedValues and setting the isLoading property on the state, and having the table data set into the state inside a useEffect. This combination seems to cause the error. Taking away any of these stops the error. i.e remove the enableFacetedValues prop, or remove the isLoading prop from state, or have the items initially populated when component loads rather than after a useEffect has run.
import { useMemo, useEffect, useState } from "react";
import {
MaterialReactTable,
useMaterialReactTable,
type MRT_ColumnDef,
} from "material-react-table";
//example data type
type Person = {
name: {
firstName: string;
lastName: string;
};
address: string;
city: string;
state: string;
};
//nested data is ok, see accessorKeys in ColumnDef below
const data: Person[] = [
{
name: {
firstName: "John",
lastName: "Doe",
},
address: "261 Erdman Ford",
city: "East Daphne",
state: "Kentucky",
},
{
name: {
firstName: "Jane",
lastName: "Doe",
},
address: "769 Dominic Grove",
city: "Columbus",
state: "Ohio",
},
{
name: {
firstName: "Joe",
lastName: "Doe",
},
address: "566 Brakus Inlet",
city: "South Linda",
state: "West Virginia",
},
{
name: {
firstName: "Kevin",
lastName: "Vandy",
},
address: "722 Emie Stream",
city: "Lincoln",
state: "Nebraska",
},
{
name: {
firstName: "Joshua",
lastName: "Rolluffs",
},
address: "32188 Larkin Turnpike",
city: "Omaha",
state: "Nebraska",
},
];
const pause = async (pauseTimeMilliseconds: number) =>
await new Promise((resolve) => setTimeout(resolve, pauseTimeMilliseconds));
const Example = () => {
const [items, setItems] = useState<Person[]>([]);
const [isLoaded, setIsLoaded] = useState(false);
useEffect(() => {
// Simulate a fetch request
pause(100).then(() => {
setItems(data);
setIsLoaded(true);
});
}, []);
//should be memoized or stable
const columns = useMemo<MRT_ColumnDef<Person>[]>(
() => [
{
accessorFn: (row) => `${row.name.firstName} ${row.name.lastName}`,
header: "Full Name",
id: "FullName",
size: 150,
},
{
accessorKey: "name.lastName",
header: "Last Name",
size: 150,
},
{
accessorKey: "address", //normal accessorKey
header: "Address",
size: 200,
},
{
accessorKey: "city",
header: "City",
size: 150,
},
{
accessorKey: "state",
header: "State",
size: 150,
},
],
[],
);
const table = useMaterialReactTable({
columns,
data: items, //data must be memoized or stable (useState, useMemo, defined outside of this component, etc.)
enableFacetedValues: true,
state: { isLoading: !isLoaded },
});
return <MaterialReactTable table={table} />;
};
export default Example;
Also worth noting it's not just accessorFn with an issue, even using a nested accessorKey like 'name.lastname' also causes errors in the console, although the table does at least still render in this case.
"name" in deeply nested key "name.lastName" returned undefined.
at MRT_TableHeadCellFilterLabel (https://q77l7n-3001.csb.app/node_modules/.vite/deps/material-react-table.js?v=0a060451:79416:9)
at div
at https://q77l7n-3001.csb.app/node_modules/.vite/deps/material-react-table.js?v=0a060451:2906:50
at Box4 (https://q77l7n-3001.csb.app/node_modules/.vite/deps/material-react-table.js?v=0a060451:16235:19)
at div
at https://q77l7n-3001.csb.app/node_modules/.vite/deps/material-react-table.js?v=0a060451:2906:50
Minimal, Reproducible Example - (Optional, but Recommended)
https://codesandbox.io/p/devbox/boring-wilson-q77l7n
Screenshots or Videos (Optional)
No response
Do you intend to try to help solve this bug with your own PR?
No, because I do not know how
Terms
- I understand that if my bug cannot be reliably reproduced in a debuggable environment, it will probably not be fixed and this issue may even be closed.
Just to update, issue still exists with latest 3.0.1 version.
And after a bit more experimenting, it might be related to the showing of skeleton in the loading state.
If the state uses showLoadingOverlay there is no error:
state: { showLoadingOverlay: isFetching },
Whilst both of these will cause the error:
state: { isLoading: isFetching },
state: { showSkeletons: isFetching },