개인 포트폴리오 고민 상담소 #2
저번 시간에 이어서 계속 ..
일단 저번 시간에는 간단한 라이브러리들을 설치 및 세팅? 을 끝내두고 헤더와 사이드 메뉴를 완성했고
사이드 메뉴에는 리덕스 툴킷을 사용해서 관리해주고있다. 리덕스 툴킷을 사용한 이유는 이제와 생각해보니 실수로 인한..것..
사이드 메뉴의 사이즈를 높이 100퍼를 주어야하는 것 때문에 header에서 관리하지않고 layout으로 옮겨서 작업을했는데
생각해보니 높이 100퍼가 제대로 안먹었던 이유가 position abolute를 줘버렸기 때문이었다...........(fixed를 사용했어야 했는데)
이 부분을 새롭게 수정한 뒤 다시 작업을 해줘야겠다. (그래도 그 덕에 리덕스 툴킷에 대한 간단한 사용방법은 익히게됐다.)
좋게좋게 생각하고 새롭게 작업하자..
사이드 메뉴 옮겨주기
내 실수를 인정하고 후다닥 헤더로 옮겨버리자.
(리덕스 툴킷을 사용한 이유가 layout에 헤더와 사이드 메뉴 둘 다 존재했었고 그 상태를 관리하기위해 layout에 코드를 작성하기 싫고 state를 넘겨주기 번거로울 것 같아서 그렇게 작업을 했었다.)
그래도 이미 만들어 둔 사이드 메뉴 styled를 그대로 가져오면 뚝딱이라 쉽게 끝날 것 같다.
여기서 컴포넌트를 자주 분리해주면 좋다는 장점을 알게되었다..! 사이드 메뉴를 따로 컴포넌트로 만들어서 사용을 했었는데 헤더에서 그냥 사용만 해주면 끝이었다..! (기분이 좀 좋았음)
다만 여기서 이제 리덕스 툴킷을 사용한 것 까지 지워야할까? 라는 생각을 하긴했는데.. 콘솔창에 자꾸 에러가 뜨는게 보기싫어서 한번 바꿔보기로 했다.
기존에 사용중이던 리덕스 툴킷에서 만들고 커스텀 훅으로 만든 버튼을 주석처리해주고 새롭게 만들어서
props로 상태를 넘겨주고 그 상태로 사이드 메뉴를 관리해줬는데 아직까지 콘솔창에 에러가 나고있다..
결론은 일단 리덕스 툴킷으로 인한 에러는 아니라는 것이기에 그냥 리덕스 툴킷으로 만든 기능은 그대로 사용해도 될 것 같다.
일단 이 콘솔창 에러를 해결하고 넘어가고싶은데
처음 발생한 이 에러는
styled components에 넘겨줄 props인 menuState를 menustate로 소문자로 변경해주니 해결이되긴했는데
다음으로는 이러한 에러가 나타났다.. 뭐지? 제대로 사용하고 있는 것 같은데
천천히 고쳐보자,,
파이어베이스 데이터베이스 가져오기
일단 supabase를 사용하려 했다가 빠르게 포기하고 다시 파이어베이스로 넘어왔는데 공식 문서를 참고해서 데이터베이스 데이터를 가져오는 것은 쉽게 해결 됐다.
평소에는 공식문서를 잘 안보는 인간이지만,, 공식문서가 중요하다는 얘기를 듣고 열심히 보려하는 편이고 이번에는 공식문서를 통해 해결이됐다.
https://firebase.google.com/docs/firestore/quickstart?hl=ko#read_data
Cloud Firestore 시작하기 | Firebase
Google I/O 2023에서 Firebase의 주요 소식을 확인하세요. 자세히 알아보기 의견 보내기 Cloud Firestore 시작하기 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 빠른
firebase.google.com
데이터 읽기 부분의 코드를 따라하며 해결을 했으며 나는 카테고리를 총 3개 익명 고민 게시판, 비밀 고민 게시판, 잡담소를 만들 예정이기에 한번 데이터를 가져오는 코드를 세 곳에서 사용할 수 있도록 만드는 걸 목표로 했다.
useFetchData 라는 커스텀 훅을 만들어 사용하기로했고
import { collection, getDocs } from "firebase/firestore/lite";
import { db } from "../api/firebase";
import { useEffectOnce } from "usehooks-ts";
type useFetchDataProps ={
collectionName: string
}
export default function useFetchData({collectionName}: useFetchDataProps) {
useEffectOnce(()=>{
const fetchData = async () => {
try{
const querySnapshot = await getDocs(collection(db,collectionName));
querySnapshot.forEach((doc)=>{
console.log(doc.data())
})}catch(error){
console.error(`${error}에러뜨는중`)
}
}
fetchData()
})
}
위와 같이 커스텀 훅이 완성이 되었다.
처음에는 useEffect를 사용하지 않고 만들었었으며 내가 사용하려는 컴포넌트에서 useEffect안에 커스텀 훅을 넣으니 에러가 발생했었다. (훅 규칙 위반인가..? 잘 모르겠다..)
그래서 커스텀 훅 만든 곳에서 useEffect를 사용해버리자 라는 생각에 만들어주니 제대로 작동을 하고있다.
collection에서 파이어베이스 데이터베이스에 컬렉션 이름을 미리 직접 박아두는 것이 아닌 이 커스텀 훅을 사용할 때
export default function HomePage(){
useFetchData({ collectionName: 'anonymous' })
이 처럼 그 컴포넌트에서 사용할 컬렉션 이름을 넣어주기 위해 파라미터를 뚫어두었다.
위 커스텀 훅을 사용했을 때 정상적으로 작동하는지가 가장 중요하기에 시험해보기로 했다.
일단 아래와 같이 파이어베이스 데이터베이스에 컬렉션을 두가지만 미리 만들고 임시로 데이터로 사용할 문서를 하나씩 넣어두었다.
콘솔창에 데이터가 찍히게 끔 만들어 두었으니 익명게시판과 비밀게시판을 오가며 확인해봤을 때
그 페이지의 데이터를 그 페이지로 이동할 때 마다 불러오는걸 볼 수 있었다.
이제 화면을 구성해주고 글 쓰기 기능을 만들어주면 반 이상은 끝이라고 보면 될 것 같다..!
게시판 꾸미기
이제 게시판을 꾸며주어야한다.. 가장 고민되는 부분이기도 하며 시간을 많이 쓸 것 같은 부분이기도 하다.
포폴용이라 하지만 예쁜게 보기좋은법.. 그리고 카테고리 세 개의 글 목록이 모두 다른 모양을 띄고있기 때문에 고민이 더 많이되는 것 같다.
모든 게시판이 다 똑같이 표시가 된다면 한 컴포넌트를 간단히 만들어서 사용하면 되겠지만 지금 내가 구현하는 것은
익명 게시판은 닉네임이 익명이어야하기에 리스트 목록에서는 닉네임이 표시가 안될 것이고
비밀 게시판은 이 서비스의 고해성사마냥,, 서비스의 주인인 나만 볼 수 있게 표시가 될 것 이고 다른사람들은 모두 똑같은 제목으로 표시가 되게끔 만들어 둘 것..
잡담소는 말 그대로 잡담소라 유저의 닉네임, 제목, 사진? 등등 모든걸 표현해주어야하기에 게시판 마다 달라서 고민이 많이 되고있는 상태이다.
그냥 하나로 통일해버릴까 싶기도하고.. 일단 하나부터 완성을 해보자.
대충 일단 만들었고 코드를 살펴보면
import { styled } from "styled-components"
import { ListItemType } from "../types/types"
const ContainerUl = styled.ul`
width: 100%;
li{
display: flex;
justify-content: space-between;
padding: 15px;
border-bottom: 1px solid;
margin-bottom: 10px;
background-color: green;
cursor: pointer;
span:last-child{
width: 20%;
text-align: end;
}
}
`
type ListUlProps = {
listData: ListItemType[]
}
export default function ListUl({listData}:ListUlProps){
return(
<ContainerUl>
{listData.map((item:ListItemType)=>{
return(
<li key={item.title}>
<span>
{item.title}
</span>
<span>{item.date}</span>
</li>
)
})}
</ContainerUl>
)
}
이곳에서 관리해주기로 했다. 이 컴포넌트를 가지고 다른 카테고리에서 사용해준다면 넘겨주는 listData만 다르면 다른 아이템들을 불러올 수 있을 것 같다.
아직은 추측이니 시험해봐야겠다..
꽤나 생각한 대로 깔끔하고 제대로 작동하는 코드가 완성됐다..! 기분이 꽤 많이 좋을지도?
아마 추후 잡담소는 따로 리스트를 새로 디자인해서 만들까 하고 생각중이라 지금 바로 하지말고 나중에.. 하자.. 아이디어가 떠오를 때
오늘 해낸 것
오늘 이룬 것은 콘솔창에 뜨던 스타일드 컴포넌트에 대한 에러와 목록 리스트를 대충 만들어주기 그리고 데이터 가져오는 커스텀 훅 살짝 수정해주기
하나씩 살펴보면 스타일드 컴포넌트에서 정상적으로 작동하지만? 콘솔창에서 자꾸 에러를 띄워주는 상황이 발생했었다. GPT에게 물어봐도 해결이 안되는 상황이었고 오늘 다른 분들에게 물어보면서 props에 넘겨줄 때 boolean이 아닌 문자열로 넘겨주어야 한다는 html 속성값? 에 대한걸 얘기해주셔서 검색 조금 해보니 해결할 수 있는 글을 발견했다.
💅Styled-components에서 props 똑똑하게 넘겨주기 (feat. Received `true` for a non-boolean attribute)
styled-component에서 prefix를 사용하여 props를 전달해주자!
velog.io
접두사 $를 사용하게되면 이를 해결해줄 수 있다는 글이었다. 그리고 공식 문서에서도 $를 붙여서 사용하는걸 보고온 뒤 바로 사용해보았는데
props로 넘겨줄 때 $를 붙여서 이름을 지어주고 사용했더니 에러가 나타나지않게되었다..!
HTML 표준 속성때문이라는데 접두사 $를 사용하면 해결이 된다. 아주 유용하게 사용될 것 같으니 꼭 기억해두자
두번째로 데이터 받아오는 커스텀 훅을 약간 수정해줬다.
전에는 그냥 데이터만 받아와서 그냥 그 데이터 째로 넘겨주었기 때문에 무언가 꺼내쓰기가 애매했었다.
그래서 커스텀 훅에서 useState를 사용하여 그 데이터를 담아둘 곳을 만들고 담아 둔 뒤 state를 내보내주는 코드로 약간의 변경을 해주었다.
import { collection, getDocs } from "firebase/firestore/lite";
import { db } from "../api/firebase";
import { useEffectOnce } from "usehooks-ts";
import { useState } from "react";
import { ListItemType } from "../types/types";
type useFetchDataProps ={
collectionName: string
}
export default function useFetchData({collectionName}: useFetchDataProps) {
const [data,setData] = useState<ListItemType[]>([])
useEffectOnce(()=>{
const fetchData = async () => {
try{
const querySnapshot = await getDocs(collection(db,collectionName));
const fetchedData: any = [];
querySnapshot.forEach((doc)=>{
fetchedData.push(doc.data())
setData(fetchedData)
})}catch(error){
console.error(`${error}에러뜨는중`)
}
}
fetchData()
})
return data
}
이제 밖에서 사용할 때
위 처럼 받아와 사용하면 listData에 데이터가 잘 넘어와있는걸 볼 수 있고 listData를 사용해주면 끝이다.
아직까지는 코드가 깔끔하게 작성이 잘 되어가고 있는 듯 하고 모르던 부분에서도 이해가 하나씩 되어가고있다.
아마 스타일드 컴포넌트는 조금 더 예쁘게 사용하는 방법을 찾아봐야할 것 같다.