Danny
Danny

Reputation: 337

How to switch the state of buttons in react hooks after updating it through rest api?

Hey guys I am very new to react and trying to make the frontend of a blog web application. I am able to show the posts on the homepage and I am able to make the like button work without API calls, just with managing states.

Now with API call, the like button shows red(button fills with red) if the post is liked by the user and I am able to unlike it by clicking it, it changes the count and it unlike the post in the backend, but it doesn't change the button state to unlike button and it keeps on unliking it rather than switching to like button state.

If the post is not liked by the user, then the button completely disappears and doesn't show on the screen, so I am not able to like the post.

This is the code I have written, It is not a good way to write react code I think, If anyone can help resolve this issue, it would be highly enlightening as I am still learning. Please do ask for more information if needed.

This is the code.

const [liked, setLiked] = useState(null) 

    function setlikeCount(post){
        return(
            post.like_count = post.like_count + 1
        )
    }

    function setunlikeCount(post){
        return(
            post.like_count = post.like_count - 1
        )
    }

    function likePosts(post) {
        console.log('liked the post')
        return(
            axiosInstance.post('api/posts/' + post.slug + '/like/')
        )
    }   

    function unlikePosts(post) {
        console.log('unliked the post')
        return(
            axiosInstance.delete('api/posts/' + post.slug + '/like/')
        )
    }

{myposts.posts && myposts.posts.results.map((post) => {
    return (
        <h4>{post.title}</h4>
    )
}


{post.likes && post.likes.map((lik, index) => {
    console.log(user, lik.id)
    return (
    user === lik.id ? (<FavoriteRoundedIcon style={{ color: "red" }}
                key={index}
                onClick={ () =>{
                    unlikePosts(post)
                    setunlikeCount(post)
                    setLiked((liked) => liked===false)
                }} 
              />)
            :   (<FavoriteBorderRoundedIcon key={index}
                    onClick={ () =>{
                    likePosts(post)
                    setlikeCount(post)
                    setLiked((liked)=> liked===true)
                    }}
                />)
    )
    })
}

const [myposts, setPosts] = useState({
    posts: null,
})

fetching posts

useEffect(() => {
        axiosInstance.get('api/posts/myhome').then((res) => {
        const allPosts = res.data;
        setLoading(false)
        setError("")
        setPosts({ posts: allPosts })
        // console.log(allPosts.results['0'].likes['0']);
        
    })
    .catch(() => {
        setLoading(false)
        setPosts({})
        setError('Something went wrong!')
    })

    }, [setPosts])

In the code, the user has the user's id. Is it possible to check the condition like user in lik.id than user === lik.id, like how we check conditions in python?

lik looks like this [{id: 1, username: "testuser12"}]

Thanks

Upvotes: 2

Views: 807

Answers (2)

Guruparan Giritharan
Guruparan Giritharan

Reputation: 16354

You need to show the button based on the content of the array like below

{post.likes && post.likes.find(x=>x.id===user) ? 
    (<FavoriteRoundedIcon style={{ color: "red" }}
            key={index}
            onClick={ () =>{
                unlikePosts(post)
                setunlikeCount(post)
                setLiked((liked) => liked===false)
            }} 
          />)
        :   (<FavoriteBorderRoundedIcon key={index}
                onClick={ () =>{
                likePosts(post)
                setlikeCount(post)
                setLiked((liked)=> liked===true)
                }}
            />)
}

If the array has values and the user is part of the array you show red button and if the array is not defined or user is not in the array you show the other button.

Upvotes: 1

Alon Malivanchuk
Alon Malivanchuk

Reputation: 271

Firstly, your setLiked method isn't right. if you want to set it to true/false just call:

setLiked(true)

Secondary, you should init your liked state. Meaning you need to useEffect (when the component loads) and read from your API if post liked or not. But the initial value better to be false and not null.

Upvotes: 0

Related Questions