나의 개발 기록지

개인 포트폴리오 고민 상담소 #1 본문

개인 프로젝트(고민 상담소)

개인 포트폴리오 고민 상담소 #1

해기97 2023. 7. 27. 15:58

어제부터 개인 포트폴리오인 고민 상담소를 진행하기 시작했다.

 

여태 배운걸 제대로 사용을 하고있는지는 잘 모르겠지만 일단 진행하기로 했다.

(수업을 들으며 공부하는건 집중이 너무나 안되고있기에.. 무언갈 만들어보고싶었다.)

 


시작

 

일단 프로젝트를 생성해준 뒤 당장 사용할 것 몇가지만 미리 설치해주었다.

 

Router, Styled-components, fontawesome, firebase, 등등..

(테스트 도구도 설치를 해주어야하는데.. 아직은 해주지않았다.)

 

현재 까지 진행한 것에 대한 메모들이며 제대로 진행중인 것인지는 잘 모르겠다.

 

시작으로 Router로 경로를 잡아주었다.

(미리 생각해둔 페이지들에 대한 경로만)

 

라우터로 경로를 잡아줄 땐 아래와 같이 라우터를 객체로 만들어 사용을 해주었다.

import Layout from "./components/Layout";

import HomePage from "./pages/home/HomePage";
import LoginPage from "./pages/login/LoginPage";
import SecretPage from "./pages/secret/SecretPage";

const routes = [
    {
        element: <Layout/>,
        children: [
            {path: '/', element: <HomePage/>},
            {path: '/login', element: <LoginPage/>},
            {path: '/sercet', element: <SecretPage/>},
        ]
    }
]

export default routes

해당 페이지들에는 아직 큰 내용은 없으니 생략하고 넘어가도될 것 같다.

(이걸 메모해두는 이유는 라우터를 객체로 사용하는 방법에 대해 익숙해져야할 것 같아서이다.)

다른 페이지는 크게 알아볼 필요 없지만 Layout은 한번 기록해두면 좋을 것 같다.

 

import styled from "styled-components"
import Header from "./Header"
import { Outlet } from "react-router-dom"
import SideMenu from "./SideMenu"
import { useState } from "react"

const Container = styled.div`
    width: 100%;
    margin: auto;
`



export default function Layout(){

    const [sideMenuState,setSideMenuState] = useState(false)

    return(
        <Container>
            <Header/>
            <SideMenu sideMenuState={sideMenuState} />
            <Outlet/>
        </Container>
    )
}

useState는 신경쓰지 않아도 될 것 같다.

Outlet은 레이아웃을 잡아주기 위해 추가해주었고 헤더는 모든 곳을 관리해주는 Layout에 추가해주었다.

(객체로 사용하는 방식일 때 이런식으로 헤더를 추가해줬지만 평소처럼 사용했다면 App.tsx에 추가하면 될 것)

 

이정도만 기록해두면 라우터를 객체로 사용하는 방법에 대한 기록은 충분할 것 같다.

(솔직히 라우터를 사용하는 방법이 가장 간단한 것 같다.)

 


다음으로 헤더와 사이드 메뉴

 

헤더와 사이드 메뉴를 만들어주었다.

 

휴대폰 사이즈로 먼저 만들고 있기에 사진이 좀 많이 작다.

햄버거 메뉴를 오른쪽에 현재 카테고리를 왼쪽에 달아주었고 햄버거 메뉴를 누르면

이러한 사이드 메뉴가 튀어나올 예정이다.

여기서 나는 조금 고민이 생겼는데 리덕스 툴킷을 지금 사용해주는 것이 맞을지 아니면 props로 내려주는 걸로 구현하고 끝내버릴지를 고민중에있다.

(현재까지 작업하며 느낀건 옛날보단 컴포넌트를 많이 쪼개고 있다는걸 크게 느끼고있다. 덕분에 코드가 깔끔해보여서 좋다.)

 

컴포넌트를 잘 쪼개주는건 나의 코드를 정리하는 것에 도움이 크게된다.

 

일단 처음으로 useState를 사용하여 상태를 넘겨주고 관리하는걸 해보았는데 꽤나 불편함을 느끼고있다.

똑같은걸 Header에도 SideMenu에도 보내주어야하고 똑같이 타입을 잡아주어야하고 똑같이 버튼을 관리하는 함수를 양쪽에서 만들어 주어야한다.

(이럴거면 리덕스 툴킷 사용하는게 훨 배 나을 것 같은 생각이 확 들더라...)

 

그래서 리덕스 툴킷을 사용하기로 했다. 만들었던 코드를 지우고 ..

 


꽤나 빨리 사용이 된 리덕스 툴킷

 

사실 헤더 하나 (사이드 메뉴 포함) 만드는데 뭐 얼마나 걸리겠냐.. 라는 생각을 했는데 의도치않게 리덕스 툴킷도 사용하게됐다.

 

뭐.. 좋은게 좋은거니까..

(사실 리덕스 툴킷 사용법을 거의 다 까먹어서 이러는 것이다. ㅎㅎ...)

 

하나씩 보니까 기억이 조금 날 것 같은데 생각해보니 전에 사용했을 땐 App을 Provider로 감싸고 store 하나로 모든걸 관리하는 식으로 사용을 했었는데 스토어를 여러개를 만들면..? 어떻게 사용해야하지? 라는 생각을 하고 한참을 검색하고 둘러보고 생각해봤는데

 

수업 내용에서 쇼핑몰 프로젝트를 참고해서 store를 어떻게 분리하고 사용하는지 알 것 같았다.

 

현재 나는 사이드 메뉴가 나타나고 사라지게끔 만드는 버튼에 대한 기능을 만드는 것이며 그것에 대한 상태를 관리하려는 것이다. (이게 정답)

 


사이드 메뉴를 완성했다..! (리덕스 툴킷의 사용방법 메모)

 

기본적으로 slice를 관리할 store를 만들어준다.

 

npm install @reduxjs/toolkit react-redux

import { configureStore } from "@reduxjs/toolkit";

import { SideMenuSlice } from "./features/sideMenu/sideMenuSlice";

import { TypedUseSelectorHook, useDispatch, useSelector } from "react-redux";

export const store = configureStore({
  reducer:{
    sideMenu:SideMenuSlice.reducer
  }
})

export const useAppDispatch:() => typeof store.dispatch = useDispatch
export const useAppSelector:TypedUseSelectorHook<ReturnType<typeof store.getState>> = useSelector;

slice를 만들어줘야한다. (상태 및 기능을 관리해줄 곳 예시로 사이드 메뉴 버튼의 boolean을 관리)

 

import { createSlice } from "@reduxjs/toolkit";


export const SideMenuSlice = createSlice({
    name : 'sideMenuState',
    initialState : false,
    reducers:{
        toggleSideMenu:(state)=>{
            return state = !state
        }
    }
})

export default SideMenuSlice.reducer;
export const { toggleSideMenu } = SideMenuSlice.actions

위 redux-toolkit을 가지고 커스텀 훅 버튼 기능을 만들어주었다.

 

import { toggleSideMenu } from "../stores/features/sideMenu/sideMenuSlice";
import { useAppDispatch } from "../stores/store"

export default function useSideMenuBtn(){
    const dispatch = useAppDispatch();
    const toggleMenu = () => {
        dispatch(toggleSideMenu());
    };

    return toggleMenu
}

 

dispatch를 사용해서 slice에서 만들어 두었던 toggleSideMenu를 가져와 사용한다.

toggleMenu라는 함수 내에서 dispatch를 사용했고 내보내 주기를 toggleMenu함수를 내보내준다.

 

커스텀훅을 가져와 사용해주면 끝이다.

    const sideMenuBtn = useSideMenuBtn()


    return(
        <Container>
            <span>익명 고민소</span>
            <FontAwesomeIcon onClick={sideMenuBtn} icon={faBars} />
        </Container>
    )

간단하게 true false를 관리해줄 토글버튼이 완성이되었다..!

 

항상 할 때 마다 이 코드를 보면서 slice를 어떻게 만들어야할지 어떻게 store를 관리해야할지 어디에서 dispatch를 사용해야할지를 생각해주면 될 것 같다.

 

충분한 이해가 되었다 라고는 할 순 없겠지만 계속 사용하면서 사용방법에 대한 이해를 해주면 될 것 같다.

(일단 무조건 사용 방법부터 익혀버리자. 자세한 이해는 나중에... 내가 좀 더 잘해졌을 때 이해해도 충분할 것 같다.)

 

사이드 메뉴를 닫아줄 버튼도 만들어 사용해야하기에 그에 관한 코드도 기록해두고 마무리

 

import { faXmark } from "@fortawesome/free-solid-svg-icons"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"

import { styled } from "styled-components"

import SideMenuUserInfo from "./SideMenuUserInfo"
import SideMenuCategory from "./SideMenuCategory"
import useSideMenuBtn from "../Hooks/useSideMenuBtn"
import { useAppSelector } from "../stores/store"

type ContainerType = {
    menuState: boolean
}

const Container = styled.div<ContainerType>`
    position: absolute;
    top:0;
    right: ${(props)=> props.menuState ? '0px' : '-55%'};
    padding: 15px;
    width: 50%;
    background-color: aqua;
    height: 100%;
    display: flex;
    flex-direction: column;
    transition: all 0.5s;
    svg{
        position: absolute;
        left: 10px;
        top:10px;
        font-size: 2em;
    }
`

export default function SideMenu(){
    const menuState = useAppSelector((state) => state.sideMenu);

    const sideMenuBtn = useSideMenuBtn()
    return(
        <Container menuState={menuState}>
            <FontAwesomeIcon onClick={sideMenuBtn} icon={faXmark} />
            <SideMenuUserInfo/>
            <SideMenuCategory/>
        </Container>
    )
}

 

styled-components를 사용하였는데 true false일 때 위치를 변경해주는 식으로 사용을 해주었는데

위 처럼 props로 내려주어 사용하면 될 줄 알았는데

기능은 잘 작동하는데 콘솔창에 에러가 떠있다.. 무슨 에런지.. ㅋ

 

일단 여기까지가 처음 스타트의 마지막

 

 

다음 포스팅에서 더 이어가자..