Tamara
Tamara

Reputation: 120

How to set the current state to the useState hook?

I have a state to keep track when a SubMenu is opened, and toggle it when another Menu Item is clicked. It goes like this:

    const [open, setOpen] = useState();
    const toggle = (id) => setOpen(id);

    onClick={() => toggle(item.navId)}

When I click the refresh button in the browser, the current Sub Menu that is opened, closes. I believe it is because the initial state is empty. How can I keep the current Sub Menu opened after the page is reloaded/refreshed. I've been looking around and I am really not sure if I should use prevState or how to implement it to my case. Any tips or pointing a direction to a solution is much appreciated. Thanks.

Upvotes: 4

Views: 424

Answers (3)

Youssouf Oumar
Youssouf Oumar

Reputation: 45923

When you hit the refresh button of the browser, your state will take its initial value, null in your case because you are not passing anything. prevState will have the same behavior. localStorage can be a solution:

import { useState } from "react";

function App() {
  const [open, setOpen] = useState(localStorage.getItem("open"));
  const toggle = (id) => {
    setOpen(id);
    localStorage.setItem("open", id);
  };

  // ...
}

export default App;

Upvotes: 0

Michael
Michael

Reputation: 987

You need to persist the data when the browser is refreshed. As others stated using LocalStorage is a good option. I always use a custom hook I wrote for such cases:

import { useEffect, useRef, useState } from 'react';

export function useLocalStorage(key, defaultValue) {
  const [state, setState] = useState(() => {
    const valueInLocalStorage = window.localStorage.getItem(key);
    if (valueInLocalStorage) {
      return JSON.parse(valueInLocalStorage);
    }
    return defaultValue;
  });

  const prevKeyRef = useRef(key);

  useEffect(() => {
    const prevKey = prevKeyRef.current;
    if (prevKey !== key) {
      window.localStorage.removeItem(prevKey);
    }
    prevKeyRef.current = key;
    window.localStorage.setItem(key, JSON.stringify(state));
  }, [key, state]);

  return [state, setState];
}

You can then import it and use it

import { useLocalStorage } from 'hooks/uselocalStorage';
const [open, setOpen] = useLocalStorage(storageKey, initialConfig);

Upvotes: 4

Andy
Andy

Reputation: 156

You could add a query parameter for the opened sub menu. URL might look something like this: www.test.com/menu?nav=1. Then you could read the value of nav and use that for the initial state.

Upvotes: -1

Related Questions