I have been working on a simple program where I have an array of posts and want to update the individual values of each post object. For this case, I want to update the number of 'likes' a post has when I click on the like button.
Here is the code I have for the reducer:
export function postReducer(state, action) {
switch(action.type) {
case 'UPDATE_LIKES':
return (
state.map(post => post.id === action.id ? {...post, likes: post.likes+=1, ...post } : {...post })
)
default:
return state
}
}
Here is the code I have for the button event calling dispatch when clicked:
export default function PostItem({ post }) {
const { dispatch } = useContext(PostContext);
return (
<div className="container">
<div className="post-stats">
<button className="post-like-button" onClick={() => dispatch({
type: 'UPDATE_LIKES', id: post.id
})}>{post.likes}</button>
</div>
</div>
)
}
The issue I'm having is that whenever I click the like button, the 'likes' value increments by 1 only after the first click and then increments by 2 each click afterwards. I want the like button to increment 'likes' by 1 every time I click it. I have tried to figure it out myself and find a solution online but had no luck. All help is appreciated :)
You appear to be mutating state in your reducer by using +=
, which may lead to unexpected behavior. Remove this and the unnecessary spread operators and the behavior should be cleaned up.
export function postReducer(state, action) {
switch(action.type) {
case 'UPDATE_LIKES':
return (
state.map(post => post.id === action.id ? {...post, likes: post.likes + 1 } : post)
)
default:
return state
}
}