Home > Mobile >  localStorage is working wrong in my application
localStorage is working wrong in my application

Time:01-09

I have a problem with the localStorage in my application. When I add items to a list of "favorites" they are stored without any problem in the localStorage, they can even be deleted by clicking them again.

But when I refresh the page, my application doesn't read that these items are in the favorites list and therefore doesn't mark them. Also, when I add a new item to the favorites list it causes it to delete everything from localStorage and start over.

Here's a gif of the localStorage view

enter image description here

Here's the code:

import React, { useState, useEffect } from 'react';
import SearchBar from '../../SearchBar/SearchBar.js';
import FiltersBox from '../FiltersBox/FiltersBox.js';
import { getItems } from '../../../Database/Database.js';
import './ItemsContainer.css';

function ItemsContainer() {
    const [items, setItems] = useState([]);
    const [search, setSearch] = useState('');

    const [favoriteItems, setFavoriteItems] = useState([]);
    let localItems = localStorage.getItem('Favorite Items');

    const [sortPrice, setSortPrice] = useState('');
    const [filterCategory, setFilterCategory] = useState('');

    const addItemToFavorites = item => {
        let existentItem = favoriteItems.find(favItem => favItem.id === item.id);

        if (existentItem) {
            let filterTheExistentItem = favoriteItems.filter(
                favItem => item.title !== favItem.title
            );

            setFavoriteItems(filterTheExistentItem);

            let stringItems = JSON.stringify(filterTheExistentItem);
            localStorage.setItem('Favorite Items', stringItems);
        } else {
            setFavoriteItems([...favoriteItems, item]);

            let stringItems = JSON.stringify([...favoriteItems, item]);
            localStorage.setItem('Favorite Items', stringItems);
        }
    };

    const filteredItemsList = () => {
        let newItemList = [];

        newItemList = items.filter(item => {
            if (filterCategory !== '' && filterCategory !== 'none') {
                return item.category === filterCategory;
            } else {
                return item;
            }
        });

        if (sortPrice === 'ascending') {
            return newItemList.sort((a, b) => (a.price > b.price ? 1 : -1));
        } else if (sortPrice === 'descending') {
            return newItemList.sort((a, b) => (b.price > a.price ? 1 : -1));
        } else {
            return newItemList;
        }
    };

    function onSortSelected(sortValue) {
        setSortPrice(sortValue);
    }

    function onCategorySelected(categoryValue) {
        setFilterCategory(categoryValue);
    }

    useEffect(() => {
        getItems().then(res => setItems(res));
    }, []);

    useEffect(() => {
        let xd = JSON.parse(localItems);
        console.log(xd);
    }, [localItems]);

    return (
        <div>
            <SearchBar setSearch={setSearch} />
            <FiltersBox
                items={items}
                setItems={setItems}
                onSortSelected={onSortSelected}
                onCategorySelected={onCategorySelected}
            />
            <div>
                {filteredItemsList()
                    .filter(item =>
                        search.toLowerCase() === ''
                            ? item
                            : item.title.toLowerCase().includes(search)
                    )
                    .map(item => (
                        <div key={item.id}>
                            <div>{item.title}</div>
                            <button
                                className={favoriteItems.includes(item) ? 'si' : 'no'}
                                onClick={() => addItemToFavorites(item)}>
                                Add to favorites
                            </button>
                        </div>
                    ))}
            </div>
        </div>
    );
}

export default ItemsContainer;

And here I leave a GIF with a continuous console.log of the localStorage:

enter image description here

I tried everyrhing, and I don't know what is happening.



Update:

Ok, I tried user @dbuchet's answer and it works fine. The little problem now is when I click the button again to remove the item from the favorites list, it doesn't delete it, it just clones it inside the array.

Here are the changes in the code:

const addItemToFavorites = item => {
        let existentItem = favoriteItems.find(favItem => favItem.id === item.id);

        if (existentItem) {
            let filterTheExistentItem = favoriteItems.filter(
                favItem => item.title !== favItem.title
            );

            setFavoriteItems(filterTheExistentItem);

            let stringItems = JSON.stringify(filterTheExistentItem);
            localStorage.setItem('Favorite Items', stringItems);
        } else {
            setFavoriteItems([...favoriteItems, item.id]);

            let stringItems = JSON.stringify([...favoriteItems, item.id]);
            localStorage.setItem('Favorite Items', stringItems);
        }
    };
<button
    className={favoriteItems.includes(item.id) ? 'si' : 'no'}
    onClick={() => addItemToFavorites(item)}>

    Add to favorites
</button>

enter image description here



Update:

Now everything works fine! Here are the last changes:

const addItemToFavorites = item => {
        let existentItem = favoriteItems.includes(item.id);

        if (existentItem) {
            let filterTheExistentItem = favoriteItems.filter(
                favItemId => favItemId !== item.id
            );

            setFavoriteItems(filterTheExistentItem);

            let stringItems = JSON.stringify(filterTheExistentItem);
            localStorage.setItem('Favorite Items', stringItems);
        } else {
            setFavoriteItems([...favoriteItems, item.id]);

            let stringItems = JSON.stringify([...favoriteItems, item.id]);
            localStorage.setItem('Favorite Items', stringItems);
        }
    };

CodePudding user response:

You're retrieving your items in localItems and... you do nothing with this variable. You should initialize your state favoritesItems with your local storage

const getItemsFromLocalStorage = () => {
  const items = localStorage.getItem('Favorite Items');
  return items ? JSON.parse(items) : [];
}


const [favoriteItems, setFavoriteItems] = useState(getItemsFromLocalStorage())

CodePudding user response:

This is where the culprit is:

    const [favoriteItems, setFavoriteItems] = useState([]);
    let localItems = localStorage.getItem('Favorite Items');

You load localStorage into localItems, but you expect it to be in favoriteItems, where you have never assigned it. You would need to specify the item of localStorage as the initial state, like:

    let localItems = localStorage.getItem('Favorite Items');
    const [favoriteItems, setFavoriteItems] = useState(localItems ? localItems : []);
  • Related