What is the best practice to reset the `useState` from localstorage, after appending new data to localstorage?

Viewed 21

I have React/typescript app and I want to read data from local storage and add data on mouseclick even, I have created a custom hook

const useLocalStorage = (name: string, defaultValue: []) => {
  const [currentValue, setCurrentValue] = useState(
    JSON.parse(localStorage.getItem(name) as any) ?? defaultValue
  )

  useEffect(() => {
    localStorage.setItem(name, JSON.stringify(currentValue))
  }, [currentValue])

  return [currentValue, setCurrentValue]
}

export default useLocalStorage

then I initiate the state into my component

import useLocalStorage from './hooks/useLocalStorage'
....
const [localData, setLocalData] = useLocalStorage('addresses', [])
....

then I have the event handler listening mouse click to add an address to the exciting array of addresses in the local storage, all working fine, but the dom isn't updating with the new list of array unless I refresh the window, so my question what is the best way to handle this issue and it there anyway to make useEffect handle this

  const AddRToLocalStorage = (addressText: string, index?: number): void => {
    if (!localStorage.getItem('addresses')) {
      localStorage.setItem(`addresses`, JSON.stringify(addressText))
    } else {
      const addressList = JSON.parse(
        localStorage.getItem('addresses') as string
      )
      addressList.push(addressText)
      localStorage.setItem('addresses', JSON.stringify(addressList))
      // setLoadingData(localStorage.getItem('addresses') as []) # this didn't work
      // window.location.reload() ## I don't want to do this
    }
  }

Note that I don't want to use window.location.reload()

1 Answers

You should be updating the local React state and let the useLocalStorage hook persist the state updates to localStorage instead of manipulating localStorage directly outside the React component lifecycle. When you update the local state React will trigger the rerender.

Example:

import useLocalStorage from './hooks/useLocalStorage';

...

const [localData, setLocalData] = useLocalStorage('addresses', []);

...

const AddRToLocalStorage = (addressText: string, index?: number): void => {
  setLocalData(addresses => [...addresses, addressText]);
}
Related