현재 프론트엔드 팀원들이 기본적인 공부만으로는 힘들어하고 있어, 추가적인 공부를 진행하기 어렵다고 느껴집니다. 이에 따라, 개인적으로 고급 프로젝트에 적용해볼 기술들을 정리하려고 합니다. 1탄인 이유는 추가적으로 더 도전할 수 있는 것들이 있을까봐 제목으로 남겨놨습니다 ㅎ
1. styled-components
npm install styled-components
npm 으로 설치 후 사용이 가능합니다.
기존 코드는 아래의 코드와 같이 별도의 파일을 분리하여 코드를 작성하였습니다.
import React from 'react';
import styles from './styles.module.css';
const App = () => {
return (
<div className={styles.container}>
<button className={styles.button}>클릭하기!</button>
</div>
);
};
export default App;
.container {
background-color: lightgray;
padding: 20px;
border-radius: 10px;
}
.button {
background-color: darkblue;
color: white;
padding: 10px 20px;
border: none;
border-radius: 5px;
cursor: pointer;
}
.button:hover {
background-color: blue;
}
근데 styled-components는 한 파일에서 작성하기 때문에, 코드들이 서로 가까워 유지보수에 용이합니다.
import React from 'react';
import styled from 'styled-components';
const Container = styled.div`
background-color: lightgray;
padding: 20px;
border-radius: 10px;
`;
const Button = styled.button`
background-color: darkblue;
color: white;
padding: 10px 20px;
border: none;
border-radius: 5px;
cursor: pointer;
@media (max-width: 768px) { //미디어쿼리도 가능!
background-color: lightcoral;
}
&:hover{ //&는 현재 요소를 참조
background-color: blue;
}`;
const App = () => {
return (
<Container>
<Button className={styles.button}>클릭하기!</Button>
</Container>
);
};
export default App;
javascript 파일에 코드를 넣다보니 파일 크기가 커진다는 단점이 있습니다... 근데도 도전해보고 싶어서 시도하려고 합니다. 이 부분은 팀원들께 속성강의를 진행 후 다같이 진행할 예정입니다.
(Tailwind와 styled-component 둘 중 고민했는데, styled-components로 픽스하려고 합니다 ㅎ)
2. 아키텍처 설계
src/
├── components/
│ ├── common/
│ ├── layout/
│ └── index.ts
├── features/
│ ├── auth/
│ └── profile/
├── hooks/
├── pages/
│ ├── api/
│ ├── auth/
│ └── index.tsx
├── services/
├── stores/
│ ├── authContext.tsx # 인증 상태 관리
│ └── userContext.tsx # 사용자 정보 상태 관리
├── styles/
│ ├── globalStyles.ts # 전역 스타일 정의
│ ├── theme.ts # 다크/라이트 테마 설정
│ └── variables.ts # 색상, 폰트 등 변수
├── types/
│ ├── auth.ts # 인증 관련 타입 정의
│ ├── user.ts # 사용자 정보 타입 정의
│ └── api.ts # 공통 API 응답 타입
└── utils/
├── formatDate.ts # 날짜 포맷팅 함수
└── validate.ts # 유효성 검사 함수
프로젝트 구조에 아키텍처를 설계해서 넣기를 실행할 예정입니다. 이번에 프론트엔드장을 맡았고, 인증/인가 파트를 제가 맡겠다고 해서 초기세팅을 할 때나 제 역할에 맞는 파일들을 작성하다보면 거의 모든 폴더를 건드리지 않을까 싶습니다 ㅎ
(theme.ts에서 다크/라이트 모드는 초급이나 중급 때 항상 해보려고 하다가 시간이 부족해서 못했는데, 이번에야 말로 시간이 널널하다면 무조건 해보고 싶습니다ㅠㅠㅠ)
3. 배포시 docker 사용해서 컨테이너화
사실 docker에 대해서 들어보긴 했지만, 진짜 응용을 위해 공부하려고 다시 검색해보니... 헤헤 모르겠습니다. 그래서 이 부분은 프로젝트 시작 전에 완벽히 공부하고 도전해보겠습니다.
4. zustand 사용하기
사실 전역 상태 관리는 Context API로 해도 되지만, 다른 방법도 있습니다. recoil, redux, jotai 등등 다양합니다.
그 중 redux는 어려우니 pass...ㅎ
사실 jotai와 zustand 중 고민을 했으나, atom이 아닌 하나의 스토어에 중앙 집중형 (이게 star형이였나..?) 스토어 내부에서 상태를 관리를 하는 zustand로 결정했습니다. 리액트 훅 기반으로 useStore 훅을 사용하고 경량 문제 때문에 고른 이유도 있습니다. 다른 곳에서 무거우면 어딘가에서 가볍게...ㅋㅋㅋ
import create from 'zustand';
interface AuthState {
user: string | null;
token: string | null;
login: (user: string, token: string) => void;
logout: () => void;
}
const useAuthStore = create<AuthState>((set) => ({
user: null,
token: null,
login: (user, token) => set({ user, token }),
logout: () => set({ user: null, token: null })
}));
export default useAuthStore;
아마도 typescript + zustand 이용하면 이런 식이지 않을까 싶습니다.
5. react-hook-form + zod 라이브러리
npm install react-hook-form zod @hookform/resolvers
다운로드... 후 import 하기
import { useForm } from 'react-hook-form';
import { z } from 'zod';
import { zodResolver } from '@hookform/resolvers/zod';
그 후 1. zod 스키마 정의 2. 타입스크립트 타입 정의하기(zod 스키마와 자동으로 타입 연결) 3. resolver로 유효성 검사하기
//1. 스키마 정의
const schema = z.object({
email: z.string().email('잘못된 이메일 주소').nonempty('이메일은 필수 요소'),
password: z
.string()
.min(8, '8자 이상 입력')
.nonempty('비밀번호는 필수 요소'),
});
// 2. TS 타입 정의
type FormData = z.infer<typeof schema>; //스키마 타입을 추론..?
// 3. react-hook-form 훅 사용
const LoginForm = () => {
const { register, handleSubmit, formState: { errors } } = useForm<FormData>({
resolver: zodResolver(schema), // zod 유효성 검사
});
// ... (다른 코드들)
return (
<form onSubmit={handleSubmit(onSubmit)}>
<div>
<label>Email</label>
<input {...register('email')} />
{errors.email && <span>{errors.email.message}</span>}
</div>
<div>
<label>Password</label>
<input type="password" {...register('password')} />
{errors.password && <span>{errors.password.message}</span>}
</div>
)
넵 로그인 부분 유효성 검사는 이렇게 작성될 수 있습니다. validation에 관해서 많은 것들이 있으니, 공식 문서를 참조해보아야겠습니다!
https://zod.dev/?id=coercion-for-primitives
1번 2번은 확실히 알지만, 3~5번은 최근에 개념을 찾아봤기 때문에 개념이 엉성합니다. 프로젝트 남은 기간 동안 완벽하게 숙지해야겠습니다..ㅎ 프로젝트 화이팅...
+ Github Action
+ axios 대신에 ky나 got 라이브러리 사용에 대해서 작성할 것이 생겼습니다..ㅎ 2탄에서 작성하겠습니다.
'추가공부' 카테고리의 다른 글
Context API 활용하기 + next.js->typescript로 (8) | 2024.12.18 |
---|---|
모르는 거 확실하게 알고 넘어가기! (4) | 2024.12.17 |