We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
分割したコンポーネントをそれぞれファイルに分けることで、管理や保守がしやすくなります。以下は、ファイル構成の例です。
まず、PostComponent 用に専用のディレクトリを作成し、分割したコンポーネントをその中に保存します。以下のような構成にするのが一般的です。
PostComponent
src/ ├── components/ │ ├── PostComponent/ │ │ ├── PostComponent.tsx # メインのコンポーネント │ │ ├── PostHeader.tsx # ヘッダー部分のコンポーネント │ │ ├── PostBody.tsx # 本文部分のコンポーネント │ │ ├── PostFooter.tsx # フッター部分のコンポーネント │ │ └── index.ts # 各コンポーネントのエクスポート │ └── ...
PostComponent.tsx
PostHeader
PostBody
PostFooter
PostHeader.tsx
PostBody.tsx
PostFooter.tsx
index.ts
// src/components/PostComponent/index.ts export { default as PostComponent } from "./PostComponent"; export { default as PostHeader } from "./PostHeader"; export { default as PostBody } from "./PostBody"; export { default as PostFooter } from "./PostFooter";
index.ts のおかげで、他のファイルで PostComponent を使用する際、ディレクトリごと簡単にインポートできます。
import { PostComponent } from "@/components/PostComponent";
このようにディレクトリごとに整理すると、各コンポーネントが独立してわかりやすくなり、保守性が向上します。
PostComponent はいくつかの異なる機能を持つため、それぞれの機能ごとにコンポーネントとして分離することで、コードの再利用性と可読性を高められます。以下のように分離するのはいかがでしょうか?
投稿したユーザーのプロフィールや投稿日を表示する部分を別コンポーネントにします。
import React from "react"; import { MoreVert } from "@mui/icons-material"; import { format } from "timeago.js"; import Image from "next/image"; import Link from "next/link"; import { User } from "@/types/user"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; interface PostHeaderProps { user: User | null; postId: string; createdAt: Date; } const PostHeader: React.FC<PostHeaderProps> = ({ user, postId, createdAt }) => ( <div className="flex justify-between items-center mb-4"> <div className="flex items-center"> <Link href={{ pathname: "/profile", query: user?.username ? { username: user.username } : {}, }} className="no-underline flex items-center" > {user?.profilePicture ? ( <Image src={`/assets/person/${user.profilePicture}`} alt="user-profile-picture" className="w-8 h-8 rounded-full object-cover" width={32} height={32} /> ) : ( <PersonIcon className="w-8 h-8 rounded-full" /> )} <span className="ml-2 text-sm font-semibold">{user?.username}</span> </Link> <span className="text-xs ml-2">{format(createdAt)}</span> </div> <DropdownMenu> <DropdownMenuTrigger> <MoreVert /> </DropdownMenuTrigger> <DropdownMenuContent> <Link href={{ pathname: "/post-edit", query: { "post-id": postId } }}> <DropdownMenuItem>Edit</DropdownMenuItem> </Link> <DropdownMenuItem>Block</DropdownMenuItem> <DropdownMenuItem>Report</DropdownMenuItem> </DropdownMenuContent> </DropdownMenu> </div> ); export default PostHeader;
投稿内容(テキストや画像など)を表示するコンポーネントです。
import React from "react"; interface PostBodyProps { desc: string; } const PostBody: React.FC<PostBodyProps> = ({ desc }) => ( <div className="my-5"> <span className="block text-base">{desc}</span> {/* TODO: 投稿記事の画像 */} </div> ); export default PostBody;
いいねボタンやコメント数を表示する部分を担当します。
import React from "react"; import FavoriteIcon from "@mui/icons-material/Favorite"; interface PostFooterProps { like: number; isLiked: boolean; handleLike: () => void; } const PostFooter: React.FC<PostFooterProps> = ({ like, isLiked, handleLike }) => ( <div className="flex items-center justify-between"> <div className="flex items-center"> <FavoriteIcon className={`cursor-pointer w-6 h-6 mr-1 ${isLiked ? "text-red-500" : "text-gray-500"}`} onClick={handleLike} /> <span className="text-base">{like}</span> </div> </div> ); export default PostFooter;
上記のコンポーネントを使って PostComponent を再構築します。
import React, { useEffect, useState } from "react"; import axios from "axios"; import { USERS_ENDPOINT, POSTS_ENDPOINT } from "@/constants/api"; import LoadingSpinner from "@/components/elements/loadingSpinner/LoadingSpinner"; import { useAppSelector } from "@/hooks/useSelector"; import { Post as PostType } from "@/types/post"; import { User } from "@/types/user"; import PostHeader from "./PostHeader"; import PostBody from "./PostBody"; import PostFooter from "./PostFooter"; interface PostProps { post: PostType; } const PostComponent: React.FC<PostProps> = ({ post }) => { const { user: currentUser } = useAppSelector((state) => state.auth); const [like, setLike] = useState<number>(post.likes ? post.likes.length : 0); const [isLiked, setIsLiked] = useState<boolean>(false); const [user, setUser] = useState<User | null>(null); const [isLoading, setIsLoading] = useState<boolean>(true); useEffect(() => { const fetchUser = async () => { setIsLoading(true); try { const response = await axios.get<User>(USERS_ENDPOINT, { params: { userId: post.userId }, }); setUser(response.data); } catch { alert("エラーが発生しました。"); } finally { setIsLoading(false); } }; fetchUser(); }, [post.userId]); const handleLike = async () => { try { await axios.put(`${POSTS_ENDPOINT}/${post._id}/like`, { userId: currentUser?._id, }); setLike(isLiked ? like - 1 : like + 1); setIsLiked(!isLiked); } catch { alert("エラーが発生しました。"); } }; return ( <> {isLoading ? ( <LoadingSpinner /> ) : ( <div className="w-full shadow-md rounded-lg mt-2 p-2"> <PostHeader user={user} postId={post._id} createdAt={post.createdAt} /> <PostBody desc={post.desc} /> <PostFooter like={like} isLiked={isLiked} handleLike={handleLike} /> </div> )} </> ); }; export default PostComponent;
The text was updated successfully, but these errors were encountered:
No branches or pull requests
分割したコンポーネントをそれぞれファイルに分けることで、管理や保守がしやすくなります。以下は、ファイル構成の例です。
ディレクトリ構成の例
まず、
PostComponent
用に専用のディレクトリを作成し、分割したコンポーネントをその中に保存します。以下のような構成にするのが一般的です。各ファイルの保存内容
PostComponent.tsx
PostComponent
を定義するファイルです。PostHeader
,PostBody
,PostFooter
をインポートして組み合わせます。PostHeader.tsx
PostHeader
コンポーネントを定義します。PostBody.tsx
PostBody
コンポーネントを定義します。PostFooter.tsx
PostFooter
コンポーネントを定義します。index.ts
PostComponent
ディレクトリ全体を簡単にインポートできるようにします。利用例
index.ts
のおかげで、他のファイルでPostComponent
を使用する際、ディレクトリごと簡単にインポートできます。このようにディレクトリごとに整理すると、各コンポーネントが独立してわかりやすくなり、保守性が向上します。
PostComponent
はいくつかの異なる機能を持つため、それぞれの機能ごとにコンポーネントとして分離することで、コードの再利用性と可読性を高められます。以下のように分離するのはいかがでしょうか?1.
PostHeader
コンポーネント投稿したユーザーのプロフィールや投稿日を表示する部分を別コンポーネントにします。
2.
PostBody
コンポーネント投稿内容(テキストや画像など)を表示するコンポーネントです。
3.
PostFooter
コンポーネントいいねボタンやコメント数を表示する部分を担当します。
4.
PostComponent
を分離したコンポーネントで再構成上記のコンポーネントを使って
PostComponent
を再構築します。説明
PostHeader
、PostBody
、PostFooter
の3つのコンポーネントに分離し、それぞれの役割ごとにコードを整理しています。PostComponent
は、各コンポーネントを呼び出して全体のレイアウトを維持します。The text was updated successfully, but these errors were encountered: