简体   繁体   English

setState in useEffect 不能与 localStorage 一起使用

[英]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.出于某种原因,它没有在安装时将 state 设置为本地存储的值,而是变为空白。 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.我认为它可能被组件中的其他地方设置为空白,但 info.personal_1 钩子只被调用一次。 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 依赖项中添加如下信息:

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.发生这种情况是因为您没有成功setting本地存储值。 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您可以直接使用我在下面提供的自定义 React 钩子 ( useLocalStorage ) 从localStorage获取项目并将其设置到您的网络应用程序中

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>
  )
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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