controlled / uncontrolled state the treatment of undefined
Describe the bug
I don't know if this is considered a bug, it is definitely an unexpected behavior
it seems that passing undefined to state.{expanded / columnSizing/ ...} or passing undefined to {onExpandedChange / onColumnSizingChange / ...} is treated as passing a value. and the state becomes controlled.
** There is another bug specific to the expanded state, it crashes if you pass undefined, though typescript allows it. but this is minor in my opinion
Your minimal, reproducible example
https://codesandbox.io/p/sandbox/friendly-wing-nwwp2w
Steps to reproduce
if you try to to hide columns nothing will happen.
but if you comment out
state: {
columnVisibility: undefined,
},
onColumnVisibilityChange: undefined,
you can hide columns
if you comment out just onColumnVisibilityChange: undefined or just columnVisibility: undefined you still can't hide columns
Expected behavior
I think an undefined value should be treated as a "no value" and in my example, the column visibility state should be uncontrolled and I should be able to hide columns
How often does this bug happen?
Every time
Screenshots or Videos
No response
Platform
-OS macOS -Browser chrome
react-table version
v8.7.9
TypeScript version
No response
Additional context
No response
Terms & Code of Conduct
- [X] I agree to follow this project's Code of Conduct
- [X] I understand that if my bug cannot be reliable reproduced in a debuggable environment, it will probably not be fixed and this issue may even be closed.
I can try and create a PR for this if you agree that this is wrong behavior
This looks problematic to me too
+1 This is still an issue and was very confusing to run into. At the very least, it would be helpful if this was included in the docs. I ran into the issue that expanded/onExpandedChange cannot be undefined for expansion to work. I want to create a TanStack Table wrapper component that can optionally take props related to expansion, but passing those directly to useReactTable causes issues if they are undefined.
function ReactTableWrapper<T>({ expanded, onExpandedChange}: Props<T>) {
const table = useReactTable({
// Other fields...
state: {
expanded, // Becomes controlled even if this is undefined
},
onExpandedChange, // Becomes controlled even if this is undefined
});
return (
<Table table={table} />
);
}
Instead, I need to do the following, which ensures that the expanded key is only provided when it isn't undefined.
state: {
...(expanded ? { expanded } : {}),
}
It looks like the problem is how the options are handled here: https://github.com/TanStack/table/blob/827b09814c659a5d196e63c7b827858db243a9cd/packages/react-table/src/index.tsx
+1 to the above.
This isn't technically a bug per se but I definitely think it's counterintuitive and not good practice to treat the absence of a value as different than the value being undefined.
I have a use case where I want to use the same table in two places within my app, one of which maintains table state and one that doesn't. I created a wrapper component that takes in optional table state but it breaks unexpectedly due to this behavior.
function MyTable({
columnVisibility,
onColumnVisibilityChange
}: {
columnVisibility?: VisibilityState,
onColumnVisibilityChange?: OnChangeFn<VisibilityState>
}) {
const table = useReactTable({
data: someData,
columns: someColumns,
getCoreRowModel: getCoreRowModel(),
initialState: {
columnOrder: defaultVisibility,
},
state: {
columnVisibility, // breaks when this is undefined
},
onColumnVisibilityChange,
}
This is very annoying, and is kind of a foot gun. It takes a minute to understand what's going on.
+1 Would love to see this fixed
+1
It is especially annoying if you pass undefined expecting to be handled as "no value is passed", but it is handled as "undefined is passed as value" and TableState type says there should be state, but actual value for those case(at least i tried with columnOrder state) is undefined.