简体   繁体   中英

setState in useEffect not working in conjunction with localStorage

This seems unordinary. I'm attempting to simply setState on mount, but it's just going blank on me.

const [info, setState] = useState({
    user_1: '',
    user_2: '',
});

useEffect(() => {

    var personal_1 = window.localStorage.getItem('personal_1');
    var personal_2 = window.localStorage.getItem('personal_2');
    console.log(personal_1);
    if (personal_1 !== null && personal_2 !== null) {
        console.log('Make it easy')
        setState({
            ...info,
            user_1: personal_1,
            user_2: personal_2
        })
    }

}, [])

useEffect(() => {
    console.log('User personal_1 was changed to', info.user_1);
}, [info.user_1])

When I log the effects of this component mounting, it shows

personal_1
Make it easy
User personal_1 was changed to

For some reason instead of setting the state on mount to the value from local storage, it just goes blank. I thought it was probably being set back to being blank from somewhere else in the component, but the info.personal_1 hook only gets called once. Does anyone know why it might potentially be setting the local storage item, but then going blank when the storage item is a normal string?

in second useEffect dependency just add info like this:

useEffect(() => {
    if(info.user_1){
     console.log('User personal_1 was 
      changedto',info.user_1);
   }

 }, [info])

This is happening because you are not successfully setting the local storage values. Hence, the value of those items will always be blank

You can straight out use the custom React hook ( useLocalStorage ) I am providing below to get and set items from your localStorage into your web-app

Hook

import { useCallback, useState, useEffect } from "react"

// To use local storage to store, update info
export function useLocalStorage(key, defaultValue) {
  return useStorage(key, defaultValue, window.localStorage)
}

// Common code being used irresp of storage type -> local or session
function useStorage(key, defaultValue, storageObject) {
  
  // Set the "value" (in this hook's state, and return it to the component's state as well) to be the value at passed "key" in storage.
  //  Else, we set it to the defaultValue (which can be a value or a func returning a val)
  const [value, setValue] = useState(() => {
    const jsonValue = storageObject.getItem(key)
    if (jsonValue != null) return JSON.parse(jsonValue)

    if (typeof defaultValue === "function") {
      return defaultValue()
    } else {
      return defaultValue
    }
  })


  // To set a value in the storage using key-val pair
  useEffect(() => {
    if (value === undefined) return storageObject.removeItem(key)
    storageObject.setItem(key, JSON.stringify(value))
  }, [key, value, storageObject])

  // To remove value at given key 
  const remove = useCallback(() => {
    setValue(undefined)
  }, [])

  return [value, setValue, remove]
}

Using the hook in a component:

import { useLocalStorage } from "./useStorage"

export default function StorageComponent() {
  const [age, setAge, removeAge] = useLocalStorage("age", 26)

  return (
    <div>
      <div>
        {age}
      </div>
      <button onClick={() => setAge(40)}>Set Age</button>
      <button onClick={removeAge}>Remove Age</button>
    </div>
  )
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM