setState в useЭффект не работает в сочетании с localStorage

#javascript #reactjs #react-hooks

#язык JavaScript #реагирует на #реагируют-крючки

Вопрос:

Это кажется неординарным. Я пытаюсь просто установить состояние на горе, но оно просто становится пустым для меня.

 const [info, setState] = useState({  user_1: '',  user_2: '', });  useEffect(() =gt; {   var personal_1 = window.localStorage.getItem('personal_1');  var personal_2 = window.localStorage.getItem('personal_2');  console.log(personal_1);  if (personal_1 !== null amp;amp; personal_2 !== null) {  console.log('Make it easy')  setState({  ...info,  user_1: personal_1,  user_2: personal_2  })  }  }, [])  useEffect(() =gt; {  console.log('User personal_1 was changed to', info.user_1); }, [info.user_1])  

Когда я регистрирую эффекты монтажа этого компонента, он показывает

 personal_1 Make it easy User personal_1 was changed to  

По какой-то причине вместо установки состояния при монтировании в значение из локального хранилища оно просто пустеет. Я думал, что, вероятно, он снова становится пустым где-то в другом компоненте, но крючок info.personal_1 вызывается только один раз. Кто-нибудь знает, почему он потенциально может устанавливать локальный элемент хранения, но затем становится пустым, когда элемент хранения является обычной строкой?

Комментарии:

1. Постарайтесь не распространять ...info

2. Как вы устанавливаете localStorage значение для personal_1 и personal_2

3. окно. localStorage.setItem(«личное», info.personal_1); Вот как я настраиваю личное. Я попытался этого не делать … информация безрезультатна.

4. Что вы имеете в виду, когда говорите » пусто «? Уменьшается ли значение до null или оно удаляется из рендеринга? Этот фрагмент кода кажется прекрасным, поэтому, пожалуйста, опубликуйте больше кода, относящегося к info переменной состояния

Ответ №1:

Это происходит из-за того, что вы не используете setting значения локального хранилища. Следовательно, значение этих элементов всегда будет пустым

Вы можете прямо использовать пользовательский крюк реакции ( useLocalStorage ) Я предоставляю ниже, чтобы получить и установить элементы из вашего локального хранилища в ваше веб-приложение

Крюк

 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 -gt; 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(() =gt; {  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(() =gt; {  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(() =gt; {  setValue(undefined)  }, [])   return [value, setValue, remove] }  

Использование крючка в компоненте :

 import { useLocalStorage } from "./useStorage"  export default function StorageComponent() {  const [age, setAge, removeAge] = useLocalStorage("age", 26)   return (  lt;divgt;  lt;divgt;  {age}  lt;/divgt;  lt;button onClick={() =gt; setAge(40)}gt;Set Agelt;/buttongt;  lt;button onClick={removeAge}gt;Remove Agelt;/buttongt;  lt;/divgt;  ) }  

Ответ №2:

во второй зависимости useEffect просто добавьте такую информацию:

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

Комментарии:

1. Это не имеет значения, так как объект info регистрируется только один раз. Это означает, что setState вызывается только один раз, и возвращаемый объект info по-прежнему пуст для 2 полей.