-
Notifications
You must be signed in to change notification settings - Fork 353
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[bug]: View Options do Not Persist when Search Params Change #893
Comments
I ended up putting the user's "View Selection" in the URL state, so it will trigger suspense boundary similar to other search params. This works ok given the # of columns is finite - so the URL can't grow too large. I combat ugly urls by only storing values as they differ from a "default" set provided to the main table hook. The custom parser that serializes/deserializes non-default view state to the URL const VisibilityStateSchema = z.record(z.string(), z.boolean());
function findInADiffThanB(
recordA: Record<string, boolean>,
recordB: Record<string, boolean>,
): Record<string, boolean> {
const difference: Record<string, boolean> = {};
for (const [kA, vA] of Object.entries(recordA)) {
const vB = recordB[kA];
if (vA !== vB) {
difference[kA] = vA;
}
}
return difference;
}
export const getVisibilityStateParser = (defaults: Record<string, boolean>) => {
return createParser<z.infer<typeof VisibilityStateSchema>>({
parse: (value) => {
try {
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
const parsed = JSON.parse(value);
const result = VisibilityStateSchema.safeParse(parsed);
return {
...defaults,
...(result.success ? result.data : {}),
};
} catch {
return null;
}
},
serialize: (value) => {
return JSON.stringify(findInADiffThanB(value, defaults));
},
eq: (a, b) => {
const diffA = findInADiffThanB(a, defaults);
const diffB = findInADiffThanB(b, defaults);
for (const [k, v] of Object.entries(diffA)) {
if (diffB[k] !== v) {
return false;
}
}
for (const [k, v] of Object.entries(diffB)) {
if (diffA[k] !== v) {
return false;
}
}
return true;
},
});
}; Required modifications to ...
const [columnVisibility, setColumnVisibility] = useQueryState(
"view",
getVisibilityStateParser(initialState?.columnVisibility ?? {})
.withOptions(queryStateOptions)
.withDefault(initialState?.columnVisibility ?? {}),
);
...
onColumnVisibilityChange: (v) => {
void setColumnVisibility(v);
}, Providing defaults to the hook const { table } = useDataTable({
...
initialState: {
columnVisibility: {
col_a: true,
col_b: false,
// ...
},
},
...
}); |
Expected Behavior
User's selection of viewed columns should persist when data updates.
Current Behavior
When using @sadmann7 's recommended approach to indicate loading, the View options are reset whenever params change and new data is done loading.
How to reproduce
This resets any "view"/visibility options to their default state.
The text was updated successfully, but these errors were encountered: