Reputation: 337
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
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
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