Как удалить элемент из массива, хранящегося в localstorage, если элемент уже существует, и изменить состояние кнопки - PullRequest
0 голосов
/ 09 апреля 2020

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

Компонент:

import React, { ReactNode, useState } from 'react';
interface Props {
  location?: string;
}
export const AddFavorite: React.FC<Props> = ({ location }: Props) => {
  let favorites: any = [];
  // const [favorite, setFavorite] = useState(false);
  const toggleFavoriteBtn = () => {
    const storageFavorites = localStorage.getItem('favorites');
    const index: number = favorites.indexOf(location);

    favorites = storageFavorites ? JSON.parse(storageFavorites) : [];
    if (index > -1) {
      favorites.splice(index, 1);
      // setFavorite(false);
    } else {
      favorites.push(location);
      // setFavorite(true);
    }
    localStorage.setItem('favorites', JSON.stringify(favorites));
  };
  return (
    <div>
      <button type="button" onClick={toggleFavoriteBtn}>
        {/* {favorite ? 'favorited' : 'not favorited'} */}
        favorite
      </button>
    </div>
  );
};

Для Теперь я закомментировал часть useState, но я вернусь к этому позже.

В значительной степени, если я запущу этот код и протестирую кнопку, я могу добавить и удалить местоположение без каких-либо проблем, ЕСЛИ Я не перезагружаюсь на странице или, например, добавить другое местоположение, а затем go вернуться к местоположению, которое я ранее добавил. Затем, внезапно, мой массив больше не понимает, что местоположение уже находится в массиве, и добавляет его снова, и после этого он просто идет бананом и ничего не имеет логического смысла.

Это способ, которым код настроен на начать или я что-то упустил, делая что-то?

Во-вторых, я добавил часть useState, которая закомментирована прямо сейчас, потому что единственная причина, по которой я хотел ее использовать, заключается в возможности изменить внешний вид кнопка, когда местоположение является предпочтительным или нет. Тем не менее, это полностью разрушает мою функцию (хотя я не могу понять, почему это могло даже повлиять на это), и вместо удаления и добавления элемента в обычном вопросе, для каждого щелчка он просто идет в этом нелогичном l oop of:

  1. добавление местоположения
  2. добавление местоположения снова (так что теперь оно дважды в массиве)
  3. удаление одного из дубликатов местоположения

(каждый шаг - это щелчок) Так что в следующий раз, когда вы нажмете 3 раза, останется 2 таких же места, а в следующий раз будет 3 и так далее и так далее.

Возможно, это связано с тем, что useState выполняет странную перезагрузку страницы, так что на самом деле это просто предыдущая ошибка или что происходит ..? ._.

1 Ответ

1 голос
/ 09 апреля 2020

Самая большая проблема, с которой вы столкнулись, это то, что вы не загружали массив избранного из localStorage при сборке компонента.

Хотя, если у вас несколько визуализируемых компонентов AddFavorite, способ, которым я изменил это потерпит неудачу, потому что массив избранных не будет обновляться, когда другой компонент вносит изменения.

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

import React, { ReactNode, useState, useEffect } from 'react';
interface Props {
  location?: string;
}
export const AddFavorite: React.FC<Props> = ({ location }: Props) => {
  let [favorites, setFavorites] = useState(():any[]=>JSON.parse(localStorage.getItem('favorites')||'[]'));
  const favorite = favorites.includes(location);
  // const [favorite, setFavorite] = useState(false);
  useEffect(() => {
    const funct =  ()=>{
      setFavorites(JSON.parse(localStorage.getItem('favorites')||'[]'));
    };
    window.addEventListener('storage',funct);
    return () => {
      window.removeEventListener('storage',funct);
    }
  }, [])
  const toggleFavoriteBtn = () => {
    const index: number = favorites.indexOf(location);
    const newFavorites = favorites.slice();
    if (index > -1) {
      newFavorites.splice(index, 1);
      // setFavorite(false);
    } else {
      newFavorites.push(location);
      // setFavorite(true);
    }
    setFavorites(newFavorites);
    localStorage.setItem('favorites', JSON.stringify(newFavorites));
  };
  return (
    <div>
      <button type="button" onClick={toggleFavoriteBtn}>
        {favorite ? 'favorited' : 'not favorited'}
        favorite
      </button>
    </div>
  );
};
...