React Hooks LocalStorage, элементы переопределения setState - PullRequest
0 голосов
/ 05 августа 2020

Я борюсь с перехватчиками React с использованием useEffect в случае сохранения задач в localstorage, поэтому при обновлении страницы все равно будут обрабатываться элементы из списка. Проблема в том, что я пытаюсь получить элементы из LocalStorage и установить их для состояния задач. Они существуют внутри localStorage, но элемент, который находится внутри состояния todos, является только одним из localstorage.

Вот компонент, который обрабатывает это:

  const [todos, setTodos] = useState([]);
  const [todo, setTodo] = useState("");

  const addTask = (event) => {
    event.preventDefault();
    let newTask = {
      task: todo,
      id: Date.now(),
      completed: false,
    };
    setTodos([...todos, newTask]);
    setTodo("");
  };
  
    const getLocalStorage = () => {
      for (let key in localStorage) {
        if (!localStorage.hasOwnProperty(key)) {
          continue;
        }
        let value = localStorage.getItem(key);
        try {
          value = JSON.parse(value);
          setTodos({ [key]: value });
        } catch (event) {
          setTodos({ [key]: value });
        }
      }
    };
  
    const saveLocalStorage = () => {
      for (let key in todos) {
        localStorage.setItem(key, JSON.stringify(todos[key]));
      }
    };
  
    useEffect(() => {
      getLocalStorage();
    }, []);
  
    useEffect(() => {
      saveLocalStorage();
    }, [saveLocalStorage]);
  
    const testClick = () => {
      console.log(todos);
    };
return (
    <div className="App">
      <h1>What would you like to do?</h1>
      <TodoForm
        todos={todos}
        value={todo}
        inputChangeHandler={inputChangeHandler}
        addTask={addTask}
        removeCompleted={removeCompleted}
      />

      {/* <TodoList todos={todos} toogleCompleted={toogleCompleted} /> */}
      <button onClick={testClick}>DISPLAY TODOS</button>
    </div>
  ); 

console of todos state

local storage part

Second problematic error while refreshing page:

новая ошибка

Кроме того, я не могу отображать элементы после получения их из локального хранилища. Возможно, я упустил какую-то глупую мелочь, но я застрял в этом моменте, и мне было интересно, возможно ли небольшое объяснение того, где я делаю ошибку.

1 Ответ

0 голосов
/ 05 августа 2020

Я думаю, вы все вместе перезаписываете значение состояния. Вы хотите добавить к тому, что существует в состоянии задачи. Вы можете использовать оператор распространения, чтобы установить в задачу все, что уже есть, плюс новое значение.

Примерно так:

setTodos ({... todos, [key ]: value});

setTodos([...todos,  [key]: value ]);
  • Обратите внимание, что оператор распространения - это мелкий клон. Если у вас есть более глубокий объект (я думаю, более двух слоев), используйте что-то вроде cloneDeep из библиотеки loda sh.

Чтобы увидеть, что происходит, измените этот блок, чтобы добавить console.logs

try {
  value = JSON.parse(value);
  setTodos({ [key]: value });
  console.log(todos);

} catch (event) {
  console.log('There was an error:', error);
  // Should handle the error here rather than try to do what failed again
  //setTodos({ [key]: value });
}

Изменить: относительно добавленной вами ошибки.

Вы пытаетесь использовать карту для объекта. map - это функция массива.

Вместо этого вы должны преобразовать свой объект в массив, а затем обратно:

const myObjAsArr = Object.entries(todos).map(([k,v]) => {
    // Do stuff with key and value
}
const backToObject = Object.fromEntries(myObjAsArr);

Измените это, чтобы установить массив (не объект):

setTodos([...todos,  [key]: value ]);

Поместите журналы консоли повсюду, чтобы вы могли видеть, что происходит.

...