Persisting component state only if navigated back to this page

Viewed 40

I have a list of entities and a few filters (date range, name etc.) to fetch those entities. On each entity I have a link redirecting to the details of this entity.

I would like to

  1. persist state of filters when user comes back from the entity details page
  2. reset filters state to default if user navigates from other page, refreshes page etc.

I tried storing filters in localStorage but I can't find any reliable way to detect that the back button was clicked on the entities details page. Any ideas how can I achieve this?

Simplified code:

function Sample() {
  const [filters, setFilters] = React.useState();
  const [entities, setEntities] = React.useState();
  const history = useHistory();

  /***
   * 
   * Entities fetching etc....
    * 
   */

  const handleNavigateToEntity = (entity) => {
    history.push(`/entities/${entity.id}`)
  }

  return (
    <div>
        <div>...SOME FILTERS...</div>
        <ol>
            {entities.map(e => <li><button onClick={handleNavigateToEntity}></button></li>)}
        </ol>
    </div>

  )
}

What I want to achieve:

if(navigatedBackToThisPage){
   const persistedFilters = readFiltersFromStorage();
   setFilters(persistedFilters);
}
1 Answers

You can persist the state in localStorage and use the history.action string to check if the navigation action was not a "POP" action and clear localStorage and reset state.

Example:

const history = useHistory();
const [state, setState] = useState();

useEffect(() => {
  // persist any state to localStorage when it updates
  state && localStorage.setItem("state", JSON.stringify(state));
}, [state]);

useEffect(() => {
  if (history.action === "POP") {
    // if back navigation repopulate state from localStorage
    setState(JSON.parse(localStorage.getItem("state")));
  } else {
    // otherwise clear any saved state.
    localStorage.removeItem('state');
  }
}, [history.action]);

useEffect(() => {
  const clearStorage = () => {
    localStorage.removeItem("state");
  };

  // Handle page reloads
  window.addEventListener("beforeunload", clearStorage);
  return () => {
    window.removeEventListener("beforeunload", clearStorage);
  };
}, []);

Edit persisting-component-state-only-if-navigated-back-to-this-page

Related