Skip to content

Commit

Permalink
Allow state changes to be pushed to history instead if wanted # 454
Browse files Browse the repository at this point in the history
  • Loading branch information
joelvdavies committed Apr 8, 2024
1 parent 348db80 commit 978742b
Showing 1 changed file with 39 additions and 22 deletions.
61 changes: 39 additions & 22 deletions src/common/preservedTableState.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,12 @@ export const usePreservedTableState = (props?: UsePreservedTableStateProps) => {
const [searchParams, setSearchParams] = useSearchParams();
const location = useLocation();

// Keeps track of the last location state update to occurr (for detecting browser changes e.g. back button being clicked)
const lastLocationUpdate = useRef({
pathname: location.pathname,
search: location.search,
});

const urlParamName = props?.urlParamName || 'state';
const compressedState = props?.storeInUrl
? searchParams.get(urlParamName)
Expand All @@ -85,38 +91,49 @@ export const usePreservedTableState = (props?: UsePreservedTableStateProps) => {
getDefaultParsedState(unparsedState)
);

// Update when the path changes e.g. when navigating between systems (ensures
// the same pagination state is recalled when going back), seems MRT treats pagination
// slightly diferent to column order as it doesn't appear to have the same issue
useEffect(() => {
if (props?.storeInUrl) {
if (JSON.stringify(parsedState) !== unparsedState && location.pathname) {
firstUpdate.current.p = undefined;
setParsedState(getDefaultParsedState(unparsedState));
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [location.pathname]);

// Update the search params only if necessary
useEffect(() => {
if (props?.storeInUrl) {
const newUnparsedState = JSON.stringify(parsedState);
if (unparsedState !== newUnparsedState) {
// Clear search params if state is no longer needed
if (newUnparsedState !== '{}') {
searchParams.set(
urlParamName,
LZString.compressToEncodedURIComponent(newUnparsedState)
);
setSearchParams(searchParams, { replace: true });
// Only set the search params if its just a current page state change and not a browser level change
// such as clicking the back button
if (
lastLocationUpdate.current.pathname === location.pathname &&
lastLocationUpdate.current.search === location.search
) {
// Clear search params if state is no longer needed
if (newUnparsedState !== '{}') {
searchParams.set(
urlParamName,
LZString.compressToEncodedURIComponent(newUnparsedState)
);
setSearchParams(searchParams, { replace: true });
} else {
searchParams.delete(urlParamName);
setSearchParams(searchParams, { replace: true });
}
// Pre-emptively update last search location to ensure the change is not repeated below
lastLocationUpdate.current.search =
searchParams.toString() === '' ? '' : `?${searchParams.toString()}`;
} else {
searchParams.delete(urlParamName);
setSearchParams(searchParams, { replace: true });
// Update the internal state to reflect the browser level change

// Ensures the same pagination state is recalled when going back, seems MRT treats pagination
// slightly diferently to column order as it doesn't appear to have the same issue
if (lastLocationUpdate.current.pathname !== location.pathname)
firstUpdate.current.p = undefined;

lastLocationUpdate.current = {
pathname: location.pathname,
search: location.search,
};
setParsedState(getDefaultParsedState(unparsedState));
}
}
}
}, [
location,
parsedState,
props?.storeInUrl,
searchParams,
Expand Down

0 comments on commit 978742b

Please sign in to comment.