
useEffect(() => {
if (userId) {
setIsLoading(true);
Promise.all([getUserPostsIT(userId), getUserPostLite(userId)])
.then(([postsIT, postsLite]) => {
setPosts(postsIT);
setUserPostLite(postsLite);
})
.finally(() => {
setIsLoading(false);
});
}
}, [userId]);
목표: 비동기 데이터 로딩 시 사용자에게 로딩 상태 표시하기
구현 과정:
if (isLoading) {
return <div>로딩 중......</div>;
}
{posts.length > 0 ? (
<ul>
{posts.map(post => (
<li key={post.id} className="bg-white mb-[20px] px-[10px] rounded-xl py-[20px] ">
<Link href={`/survey-it/${post.id}`} className="text-xl">
{post.title}
<p className="text-base">
마감일:
{post.deadlineDate
? post.deadlineDate.toLocaleDateString('ko-KR', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
})
: 'No deadline'}
</p>
</Link>
<button onClick={() => clickDeleteITHandler(post.id)}>삭제</button>
</li>
))}
</ul>
) : (
** <p>작성한 글이 없습니다.</p>**
)}
const clickDeleteITHandler = async (postId: string) => {
const result = await Swal.fire({
title: '정말 삭제하시겠습니까?',
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
confirmButtonText: '확인',
cancelButtonText: '취소',
});
if (result.isConfirmed) {
try {
await deletePost(postId);
setPosts(prevPosts => prevPosts.filter(post => post.id !== postId));
setUserPostLite(prevPosts => prevPosts.filter(post => post.id !== postId));
Swal.fire({
title: 'Deleted!',
text: 'Your file has been deleted.',
icon: 'success',
});
} catch (error) {
console.error('Failed to delete post: ', error);
}
}
};
<Tabs
aria-label="서베이 Tab"
size="lg"
variant="underlined"
classNames={{
tabList: 'gap-6 border-b-0 font-bold w-full mb-[15px] relative rounded-none p-0 border-b border-divider',
cursor: 'w-full bg-[#0051FF]',
tab: 'max-w-fit px-0 h-12 text-xl px-2',
tabContent: 'group-data-[selected=true]:text-[#0051FF]',
}}
>
<Tab title="내가 작성한 IT 서베이">
<Card className="bg-transparent border-0 rounded-none shadow-none">
<CardBody>
{posts.length > 0 ? (
<ul>
{posts.map(post => (
<li key={post.id} className="bg-white mb-[20px] px-[10px] rounded-xl py-[20px] ">
<Link href={`/survey-it/${post.id}`} className="text-xl">
{post.title}
<p className="text-base">
마감일:
{post.deadlineDate
? post.deadlineDate.toLocaleDateString('ko-KR', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
})
: 'No deadline'}
</p>
</Link>
<button onClick={() => clickDeleteITHandler(post.id)}>삭제</button>
</li>
))}
</ul>
) : (
<p>작성한 글이 없습니다.</p>
)}
</CardBody>
</Card>
</Tab>
<Tab title="내가 작성한 참여했Surv">
<Card>
<CardBody>
{userPostLite.length > 0 ? (
<ul>
{userPostLite.map(post => (
<li key={post.id}>
<Link href="/survey-lite">{post.title}</Link>
</li>
))}
</ul>
) : (
<p>작성한 글이 없습니다.</p>
)}
</CardBody>
</Card>
</Tab>
</Tabs>
오늘의 한줄평 : 오늘은 조금 다른 방식으로 TIL을 적어보았다. 오늘 프로젝트 진행을 하면서 Next.js와 Firebase의 통합, 비동기 처리, 조건부 렌더링, UI 개선 및 사용자 경험에 대한 중요성을 또 한번 상기시켜보니 좋았다.