홈화면에서는 이쁜 링크들과 글들을 불러올 예정이다.
const [show, setShow] = useState(false);
return (
<>
<Box
...
as={motion.div}
onHoverStart={() => setShow(true)}
onHoverEnd={() => setShow(false)}
>
<Center
...
bgColor={show ? "rgba(0,0,0,0.3)" : undefined}
transition="0.5s"
>
<Center
...
as={motion.div}
animate={{
x: show ? 0 : -500,
transition: { type: "linear" },
}}
>
...
</Box>
</>
);
}
framer motion에는 onHoverStart
와 onHoverEnd
라는 매우 유용한 props들이 있다. 카드에 커서를 올리면 show를 true로 만들어준뒤, show값에 따라 애니메이션과 bgColor를 바꿀수있다.
interface IStartCardProps {
heading: string;
text: string;
src: string;
}
카드를 컴포넌트화 해준 뒤, props를 입력받는다.
여기서부터가 블로그 기능의 핵심이다.
백엔드를 잘모르던 나는 파이어베이스 공식문서와
노마드코더 파이어베이스 기초강의를 들으면서 해결해나갔다.
FireStore Database에 미리 저장해놓은 Notes들을 불러온다.
Notes
- title(제목)
- md(본문)
- category(카테고리,태그)
- createdAt(작성날짜)
- thumbnailURL(썸네일 URL)
interface INotes {
id: string;
title: string;
md: string;
category: string;
createdAt: number;
thumbnailUrl: string;
}
const [notes, setNotes] = useState<INotes[] | undefined>(undefined);
const getNotes = async (limitCount: number) => {
const q = query(
collection(dbService, "notes"),
orderBy("createdAt", "desc"),
);
onSnapshot(q, (snapshot) => {
const notesArr: any = snapshot.docs.map((note) => ({
id: note.id + "",
...note.data(),
}));
setNotes(notesArr);
});
};
useEffect(() => {
getNotes();
console.log(notes)
}, []);
콘솔로그 결과. 성공적으로 notes들을 불러왔다.
{notes?.map((note, index) => (
<Post
key={note.id}
title={note.title}
md={note.md}
thumbnailUrl={note.thumbnailUrl}
category={note.category}
createdAt={note.createdAt}
reverse={index % 2 === 0 ? true : false}
/>
))}
Post 컴포넌트를 만들어서 notes 데이터를 보여준다.
지금은 글이 적어서 괜찮지만 ,
글이 100개 200개가 되는데 글을 다 불러온다면 메인 페이지가 느려질것이다.
그래서 메인 홈페이지의 속도를 위해 모든 글들을 불러오지 않고 4개씩 보여주고
버튼을 누를때마다 4개를 더 보여주는식으로 갈것이다.
//limit할 개수
const [limitCount, setLimitCount] = useState(4);
// 버튼 클릭
const onMoreClicked = () => {
setLimitCount((prev) => prev + 4);
};
//limit
const getNotes = async (limitCount: number) => {
const q = query(
collection(dbService, "notes"),
orderBy("createdAt", "desc"),
limit(limitCount)
);
onSnapshot(q, (snapshot) => {
const notesArr: any = snapshot.docs.map((note) => ({
id: note.id + "",
...note.data(),
}));
setNotes(notesArr);
});
};
정상적으로 잘 작동한다.
본문에는 없지만 UI 디자인이 시간을 제일 많이 잡아먹었다..