Like Button with Local Storage in ReactJS

Viewed 310

I developed a Simple React Application that read an external API and now I'm trying to develop a Like Button from each item. I read a lot about localStorage and persistence, but I don't know where I'm doing wrong. Could someone help me?

1-First, the component where I put item as props. This item bring me the name of each character

<LikeButtonTest items={item.name} />

2-Then, inside component:

import React, { useState, useEffect } from 'react';
import './style.css';

const LikeButtonTest = ({items}) => {


const [isLike, setIsLike] = useState(
    JSON.parse(localStorage.getItem('data', items))
);

useEffect(() => {
    localStorage.setItem('data', JSON.stringify(items));
}, [isLike]);

const toggleLike = () => {
    setIsLike(!isLike);
}

return(
    <div>
        <button 
            onClick={toggleLike} 
            className={"bt-like like-button " + (isLike ? "liked" : "")
        }>
        </button>
    </div>
    );
};

export default LikeButtonTest;

My thoughts are:

First, I receive 'items' as props Then, I create a localStorage called 'data' and set in a variable 'isLike' So, I make a button where I add a class that checks if is liked or not and I created a toggle that changes the state

The problem is: I need to store the names in an array after click. For now, my app is generating this:

App item view

localStorage with name of character

1 Answers

You're approach is almost there. The ideal case here is to define your like function in the parent component of the like button and pass the function to the button. See the example below.

const ITEMS = ['item1', 'item2']

const WrapperComponent = () => {

    const likes = JSON.parse(localStorage.getItem('likes'))

    const handleLike = item => {
        // you have the item name here, do whatever you want with it.
        const existingLikes = likes
        localStorage.setItem('likes', JSON.stringify(existingLikes.push(item)))
    }

    return (<>
        {ITEMS.map(item => <ItemComponent item={item} onLike={handleLike} liked={likes.includes(item)} />)}
    </>)
}

const ItemComponent = ({ item, onLike, liked }) => {
    return (
        <button 
            onClick={() => onLike(item)} 
            className={liked ? 'liked' : 'not-liked'}
        }>
            {item}
        </button>
    )
}

Hope that helps!

note: not tested, but pretty standard stuff

Related