7. 게시글 구현하기
(1) 기획부터 시작
const PostCard = () => {
return (
<Card>
<Image />
<Content></Content>
<Button></Button>
</Card>
<ComentForm />
<Coment />
)
};
export default PostCard;
(2) 코드 작성
const PostCard = ({ post }) => {
const [liked, setLiked] = useState(false);
const [commentFormOpened, setCommentFormOpened] = useState(false);
const onToggleLike = useCallback(() => {
setLiked((prev) => !prev);
}, []);
const onToggleComment = useCallback(() => {
setCommentFormOpened((prev) => !prev);
}, []);
const { me } = useSelector((state) => state.user);
const id = me && me.id;
return (
<div style={{ marginBottom: 10 }}>
<Card
cover={post.Images[0] && <PostImages images={post.Images} />}
actions={[
<RetweetOutlined key="retweet" />,
liked ? (
<HeartTwoTone
twoToneColor="#eb2f96"
key="heart"
onClick={onToggleLike}
/>
) : (
<HeartOutlined key="heart" onClick={onToggleLike} />
),
<MessageOutlined key="comment" onClick={onToggleComment} />,
<Popover
key="more"
content={
<Button.Group>
{id && post.User.id === id ? (
<>
<Button>수정</Button>
<Button type="danger">삭제</Button>
</>
) : (
<Button>신고</Button>
)}
</Button.Group>
}
>
<EllipsisOutlined />
</Popover>,
]}
>
<Card.Meta
avatar={<Avatar>{post.User.nickname[0]}</Avatar>}
title={post.User.nickname}
description={post.content}
/>
</Card>
{commentFormOpened && <div>댓글 부분</div>}
{/* // <ComentForm />
// <Coment /> */}
</div>
);
};
PostCard.propTypes = {
post: PropTypes.shape({
id: PropTypes.number,
User: PropTypes.object,
content: PropTypes.string,
createdAt: PropTypes.object,
Comments: PropTypes.arrayOf(PropTypes.object),
Images: PropTypes.arrayOf(PropTypes.object),
}).isRequired,
};
8. 댓글 구현하기
const CommentForm = ({ post }) => {
const id = useSelector((state) => state.user.me?.id);
const [commentText, onChangeCommentText] = useInput("");
const onSubmitComment = useCallback(() => {
console.log(post.id, commentText);
}, [commentText]);
return (
<Form onFinish={onSubmitComment}>
<Form.Item style={{ position: "relative, margin: 0" }}>
<Input.TextArea
value={commentText}
onChange={onChangeCommentText}
rows={4}
/>
<Button
type="primary"
htmlType="submit"
style={{ position: "absolute", right: 0, bottom: -40 }}
>
삐약
</Button>
</Form.Item>
</Form>
);
};
CommentForm.propTypes = {
post: PropTypes.object.isRequired,
};
export default CommentForm;
- PostCard.js
...
{commentFormOpened && (
<div>
<CommentForm post={post} />
<List
header={`${post.Comments.length}개의 댓글`}
itemLayout="horizontal"
dataSource={post.Comments}
renderItem={(item) => (
<li>
<Comment
author={item.User.nickname}
avatar={<Avatar>{item.User.nickname[0]}</Avatar>}
content={item.content}
/>
</li>
)}
/>
</div>
)}
...
9. 이미지 구현하기
- PostImages.js
const PostImages = ({ images }) => {
const [showImagesZoom, setShowImagesZoom] = useState(false);
const onZoom = useCallback(() => {
setShowImagesZoom(true);
}, []);
if (images.length === 1) {
return (
<>
<img
role="presentation"
src={images[0].src}
alt={images[0].src}
onClick={onZoom}
/>
</>
);
}
if (images.length === 2) {
return (
<>
<img
role="presentation"
src={images[0].src}
alt={images[0].src}
onClick={onZoom}
style={{ width: "50%", display: "inline-block" }}
/>
<img
role="presentation"
src={images[1].src}
alt={images[2].src}
onClick={onZoom}
style={{ width: "50%", display: "inline-block" }}
/>
</>
);
}
return (
<>
<div>
<img
role="presentation"
src={images[1].src}
alt={images[2].src}
onClick={onZoom}
style={{ width: "50%" }}
/>
<div
role="presentation"
onClick={onZoom}
style={{
display: "inline-block",
width: "50%",
textAlign: "center",
verticalAlign: "middle",
}}
>
<PlusOutlined />
<br />
{images.length - 1}
개의 사진 더보기
</div>
</div>
</>
);
};```