02_lesson: Added ReactionButton for emoji thumbs up/down
parent
1d970d5879
commit
47e543f2b4
|
@ -1,7 +1,8 @@
|
||||||
import { useSelector } from "react-redux";
|
import { useSelector } from 'react-redux';
|
||||||
import { selectAllPosts } from "./postsSlice";
|
import { selectAllPosts } from './postsSlice';
|
||||||
import PostAuthor from "./PostAuthor";
|
import PostAuthor from './PostAuthor';
|
||||||
import TimeAgo from "./TimeAgo";
|
import TimeAgo from './TimeAgo';
|
||||||
|
import ReactionButtons from './ReactionButton';
|
||||||
|
|
||||||
const PostsList = () => {
|
const PostsList = () => {
|
||||||
const posts = useSelector(selectAllPosts);
|
const posts = useSelector(selectAllPosts);
|
||||||
|
@ -18,6 +19,7 @@ const PostsList = () => {
|
||||||
<PostAuthor userId={post.userId} />
|
<PostAuthor userId={post.userId} />
|
||||||
<TimeAgo timestamp={post.date} />
|
<TimeAgo timestamp={post.date} />
|
||||||
</p>
|
</p>
|
||||||
|
<ReactionButtons post={post} />
|
||||||
</article>
|
</article>
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
import { useDispatch } from 'react-redux';
|
||||||
|
import { reactionAdded } from './postsSlice';
|
||||||
|
|
||||||
|
const reactionEmoji = {
|
||||||
|
thumbsUp: '👍',
|
||||||
|
wow: '😮',
|
||||||
|
heart: '❤️',
|
||||||
|
rocket: '🚀',
|
||||||
|
coffee: '☕',
|
||||||
|
};
|
||||||
|
|
||||||
|
const ReactionButtons = ({ post }) => {
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
const reactionButtons = Object.entries(reactionEmoji).map(([name, emoji]) => {
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
key={name}
|
||||||
|
type="button"
|
||||||
|
className="reactionButton"
|
||||||
|
onClick={() =>
|
||||||
|
dispatch(reactionAdded({ postId: post.id, reaction: name }))
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{emoji} {post.reactions[name]}
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
return <div>{reactionButtons}</div>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ReactionButtons;
|
|
@ -7,12 +7,26 @@ const initialState = [
|
||||||
title: "Learning Redux Toolkit",
|
title: "Learning Redux Toolkit",
|
||||||
content: "I've heard good things.",
|
content: "I've heard good things.",
|
||||||
date: sub(new Date(), { minutes: 10 }).toISOString(),
|
date: sub(new Date(), { minutes: 10 }).toISOString(),
|
||||||
|
reactions: {
|
||||||
|
thumbsUp: 0,
|
||||||
|
wow: 0,
|
||||||
|
heart: 0,
|
||||||
|
rocket: 0,
|
||||||
|
coffee: 0,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "2",
|
id: "2",
|
||||||
title: "Slice...",
|
title: "Slice...",
|
||||||
content: "The more I say slice, the more I want pizza.",
|
content: "The more I say slice, the more I want pizza.",
|
||||||
date: sub(new Date(), { minutes: 5 }).toISOString(),
|
date: sub(new Date(), { minutes: 5 }).toISOString(),
|
||||||
|
reactions: {
|
||||||
|
thumbsUp: 0,
|
||||||
|
wow: 0,
|
||||||
|
heart: 0,
|
||||||
|
rocket: 0,
|
||||||
|
coffee: 0,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -33,15 +47,29 @@ const postsSlice = createSlice({
|
||||||
content,
|
content,
|
||||||
userId,
|
userId,
|
||||||
date: new Date().toISOString(),
|
date: new Date().toISOString(),
|
||||||
|
reactions: {
|
||||||
|
thumbsUp: 0,
|
||||||
|
wow: 0,
|
||||||
|
heart: 0,
|
||||||
|
rocket: 0,
|
||||||
|
coffee: 0,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
reactionAdded(state, action) {
|
||||||
|
const { postId, reaction } = action.payload;
|
||||||
|
const existingPost = state.find((post) => post.id === postId);
|
||||||
|
if (existingPost) {
|
||||||
|
existingPost.reactions[reaction]++; // this kind of immer action can only happen in slice
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const selectAllPosts = (state) => state.posts;
|
export const selectAllPosts = (state) => state.posts;
|
||||||
|
|
||||||
export const { postAdded } = postsSlice.actions;
|
export const { postAdded, reactionAdded } = postsSlice.actions;
|
||||||
|
|
||||||
export default postsSlice.reducer;
|
export default postsSlice.reducer;
|
||||||
|
|
Loading…
Reference in New Issue