사용한 라이브러리

김현준·2024년 3월 6일
0

리액트

목록 보기
1/11

CSS 및 스타일링

reset-css

npm i reset-css

styled-components와 연결되어, 여러 브라우저마다 기본적으로 설치되어 있는 스타일을 지워주는 Node.js 패키지

styled-components

npm i styled-components

리액트 스타일 적용에 최고 사용법(사용예시)
styled component css 적용 시 자동완성은
vscode-styled-components 익스텐션을 받으면 된다.
안 될 경우 참고:

npm i --save-dev @types/styled-components
ts용

styled-reset

npm i styled-reset

styled-components와 연결되어, 여러 브라우저마다 기본적으로 설치되어 있는 스타일을 지워주는 Node.js 패키지
하지만 이걸 사용하지 않겠다 #5.1참고
사용예시

emotion

npm i @emotion/react

JS 로 css 스타일을 작성하도록 설계된 라이브러리

react + ts + vite에서 사용 시
참고 사이트

UI 컴포넌트 라이브러리

mui

npm i @mui/material

Material Design 원칙을 기반으로 한 React 컴포넌트 라이브러리

  • 개발자가 고품질의 UI를 빠르게 구축할 수 있도록 다양한 미리 만들어진 컴포넌트를 제공
  • MUI를 사용하면 애플리케이션의 일관성과 접근성을 향상시키면서 개발 시간을 크게 단축시킬 수 있

5버전부터는 emotion을 접목시켜 보다 더 styled 컴포넌트에 가까워졌다.
emotion은 Javascript로 Css 스타일을 작성하도록 설계된 라이브러리이다.

리액트 훅 폼 사용 시
1. 컴포넌트를 사용 : Controller
2. custom hook 사용: useController ⭐추천⭐

입력 필드의 이름을 지정하는 역할 비교

//기본 HTML 요소 (register 사용 시)
<input {...register('example')} placeholder="Example" />//Material UI 컴포넌트 (Controller 사용 시)
<Controller
  name="example"
  control={control}
  render={({ field }) => <TextField {...field} label="Example" variant="outlined" />}
/>
  • Controller name="example": name prop이라고 한다.
    Material UI와 같은 커스텀 컴포넌트를 사용할 때, ...register('example')와 동일한 역할을 수행하며 폼 필드의 이름을 지정하여 폼 데이터에 접근할 수 있게 함.

shadcn/ui

테마 커스텀 사이트

라우팅

react-router-dom@5.3.4 react-query

npm i react-router-dom@5.3.4 react-query

리액트 라우터 클래식(6버전 이전)
뒤에 리액트 쿼리는 라우터 설치하는 김에 한꺼번에 설치한 거
npm i --save-dev @types/react-router-dom@5.3
리액트 라우터 ts를 위해 이것도 설치

react-router-dom

npm i react-router-dom

신버전 사용법은 리액트 라우터 공식문서, #4 [🔥2022 UPDATE] REACT ROUTER V6 참고
React-Router-Dom 개념잡기

  • 라우팅: 기본적으로 네트워크에서 경로를 선택하는 프로세스를 의미
    • 다양한 주소의 요청이 들어왔을 때 각각 맞는 콘텐츠로 이동시켜 주는 작업
    • 예시: 우체국에서 편지를 집 주소에 맞게 배달

사용하는 이유

  • SPA 사용자 경험 향상의 목적
    그냥 a 태그를 사용하면 페이지 전체가 새로 로딩된다.
    흔히 말하는 화면 깜빡임이 필수적으로 발생하고 이는 사용자 경험을 떨어뜨리는 큰 요인이다. 따라서 라우팅을 통해 부드러운 화면전환을 꾀하는 것

패칭 라이브러리

tanstack/react-query

npm i @tanstack/react-query

react 버전이 18이면 타입스크립트에서 react query를 못 불러오므로 설치해줘야 함
그리고 @tanstack/react-query에서 useQuery를 사용할때 query key의 값은 대괄호로 묶어줘야한다.

const { isLoading, data } = useQuery(["allCoins"], fetchCoins);

npm i -D @tanstack/react-query-devtools

devtools을 사용하기 위한 것
위의 리액트 쿼리 모듈을 설치했으면 이것도 따로 설치해줘야 함

SWR

npm i swr

사용법
SWR: 서버에서 데이터를 가져오는 데 사용되는 React 후크
useState와 useEffect를 사용하지 않고 실시간 데이터를 fetch, 캐싱 또는 re-fetch 할 수 있다. SWR은 캐시에서 데이터를 제공한 다음 검증을 위해 서버를 만들고 일단 완료되면 데이터 일관성을 위해 데이터를 결합한다.

HTTP 클라이언트 라이브러리

axios

Promise 기반의 HTTP 비동기 통신 라이브러리
사용법

지원하는 HTTP 메서드

  • axios.get(url[, config])
  • axios.delete(url[, config])
  • axios.post(url[, data[, config]])
  • axios.put(url[, data[, config]])
  • axios.patch(url[, data[, config]])

장점이자 활용법

커스텀 인스턴스
아래 코드처럼 쉽게 기본 인스턴스를 커스텀하게 설정 가능

axios.create({
 baseURL: host
})

baseURL, headers, params, 네트워크 상태에 따라 연결을 종료하는 timeout, 인증서버에 쓰이는 auth, 보안에 쓰이는 xsrf 토큰까지 쉽게 설정 가능하다.
방법은 baseURL 설정하듯이 key:value 형태로 JSON을 다루듯 쉽게 설정하면 된다.

요청을 취소하는 cancleToken
예를 들어 어떤 용청을 했는데 그 요청을 취소해야 하는 로직이 있다.
사용자가 취소버튼을 눌러썩나 화면의 블러 부분을 클릭했을 때다.
그럴 때 axios의 cancelToken을 활용하면 된다.

인터셉터
axios로 전달되는 요청과 응답을 가로채서 API 요청 전후로 필요한 공통된 로직을 처리를 할 수 있도록 해준다. 예를 들어 아래와 같은 인터셉터 설정을 해놓지 않으면 우리는 매번 요청을 할 때마다 에러핸들링 함수를 정의해주어야 한다.

axios.interceptors.request.use(config => {
  //요청을 보내기 전 로직
  return config
}, (err) => {

aixos는 기본적으로 200~300의 statuseCode는 정상, 그 외는 비정상으로 설정해놓기에 이를 이용해서 쉽게 statusCode에 따른 에러핸들링을 할 수 있다.

쉬운 참조
아래 코드처럼 res에 대해 data나 status 등의 정보를 쉽게 받을 ㅅ 있다.

axios
  .get('api 주소')
  .then(res => {
    consol.log(res.status)
    consol.log(res.data)
    consol.log(res.headers.server)
    consol.log(res.headers.etag)
    consol.log(res.request.host)
    consol.log(res.request.protocol)
  /*
  200
  {userId: 1, id: 1, title: 'hello world'}
  cloudflare
  \|"53-hfEnumeNh6Yirfjyjaujc0PPPT+s"
  jsonplaceholder.typicode.com
  https:
  */
  })

상태코드가 200이 아닐 경우 응답 데이터를 조회할 수 있는 방법
Axios는 상태 코드가 200대가 아닐 경우 이를 오류로 간주하고, catch 블록으로 넘어가도록 설계
예시

//응답받는 response.data의 모양
export interface MutationResult {
  code: number;
  message?: string;
}
//로그인id 체크
export async function checkLoginId(loginId: string) {
  try {
    const response = await axios.get(`/api/v1/auth/check-loginid/${loginId}`);
    return response.data;
  } catch (error) {
    const axiosError = error as AxiosError<MutationResult>;
    return axiosError.response?.data;
  }
}

여기서 중요한 점은 Axios 에러 객체가 AxiosError 타입임을 명확히 하고, 이 객체의 response 속성을 통해 응답 데이터를 확인하는 것


전역 상태 관리

recoil vs Zustand

항목RecoilZustand
설명Facebook에서 개발한 React 친화적 상태 관리 라이브러리간단하고 가벼운 React 상태 관리 라이브러리
장점- React와의 긴밀한 통합
- 모듈화된 상태 관리
- 비동기 처리 용이
- 개발 도구 지원
- 간단한 사용법
- 높은 성능
- 유연한 확장성
- 작은 번들 사이즈
단점- 러닝 커브
- 상대적으로 작은 생태계
- 성능 최적화 필요
- 기능 제한
- 일부 타입스크립트 시나리오에서 추가 설정 필요
- 작은 커뮤니티
적합한 용도복잡한 상태 관리와 비동기 처리가 필요한 대규모 애플리케이션간단하고 가벼운 상태 관리가 필요한 소규모 또는 중간 규모 프로젝트
  • 결론
    • Recoil
      복잡한 상태 관리와 비동기 처리가 필요한 대규모 애플리케이션에 적합
    • Zustand
      간단하고 가벼운 상태 관리가 필요한 소규모 또는 중간 규모 프로젝트에 적합

recoil

상태 관리를 위한 라이브러리

npm i recoil

#6.2참조
리코일은 오직 value가 필요한 컴포넌트만 그 value를 가진다. 경로를 따라 value를 계속 운반해줄 필요가 없다.

npm i recoil-persist

사용법(기본 사용법과 유저 정보 저장할 경우 등)
recoil 상태관리를 사용중이라면 로컬스토리지나 세션스토리지에 상태값을 저장하기 위해 recoil-persist를 설치하여 담을 수가 있다.

  • 📍localStorage
    사용자가 데이터를 지우지 않는 이상, 브라우저나 OS를 종료해도 계속 브라우저에 남아있음 (영구성)
    단, 동일한 브라우저를 사용할 때만 해당
    지속적으로 필요한 데이터 저장 (자동 로그인 등)
    로컬스토리지, 세션스토리지사용법
  • 📍sessionStorage
    데이터가 오리진 뿐만 아니라 브라우저 탭에도 종속되기 때문에, 윈도우나 브라우저 탭을 닫을 경우 제거
    일시적으로 필요한 데이터 저장 (일회성 로그인 정보, 입력폼 저장 등)

Zustand

간단하고 직관적인 상태 관리 라이브러리

npm i zustand

폼 관리

react-hook-form

npm i react-hook-form

차트 및 데이터 시각화

apexcharts

npm install --save react-apexcharts

import ApexChart from "react-apexcharts"; 임포트 하고
공식문서 차트 설치와 사용법
차트를 만들 수 있고, 꾸밀 수도 있다.
리액트 차트의 개요다.
시리즈로 차트에 표시하려는 데이터를 넣고
options(Reference)탭에서 많은 것을 설정 가능

SEO 관리

react-helmet

리액트 애플리케이션의 메타 데이터를 관리

npm i react-helmet

재사용 가능한 React 컴포넌트가 문서 헤드에 대한 모든 변경 사항을 관리한다.
컴포넌트인데 여기서 무엇을 render하던 그게 문서의 헤드로 간다.

드래그 앤 드롭

beautiful-dnd

npm i react-beautiful-dnd

React로 list를 만들기 위한 아름답고 접근 가능한 드래그 앤 드롭
예시, 이 주소 맨 밑에 한글로 번역된 사이트 있음
타입스크립트로 dnd 만들어보기

에러 2개
1. 안 되면 index.tsx에서 StrictMode 제거
2. React 18 에서 npm i react-beautiful-dnd 하면 에러가 발생하는데 어떻게 해결해야하나요
npm i react-beautiful-dnd --legacy-peer-deps 요거 설치
보니까 라이브러리가 요구하는 peerDependency가 ^16.8.5 || ^17.0.0이더라고요. 현재 제 버전도 ^18.1.0 이라 동일한 에러가 발생했습니다.
--legacy-peer-deps로 무시해도 되고 --force로 의존 버전을 추가 설치하는 방법이 있다고 하네요!

React 18 버전을 사용 중인데 Droppable에서 'Unable to find draggable with id' 오류 발생



React 18 버전을 사용 중이면 분명 공식 문서의 예시를 따라 했는데도 불구하고 위와 같은 오류가 나며 드래그가 작동하지 않는다.

이는 React 18 버전의 Strict Mode를 아직 react-beautiful-dnd가 지원하지 않아서 생기는 문제로, 이 문제를 해결할 수 있는 방법은 두 가지가 있다.

1. React Strict Mode를 지운다.
main.tsx 혹은 index.tsx 에서 전체 App 컴포넌트를 감싸고 있는 React.StrictMode를 지워주면 된다.

하지만 Strict Mode는 잠재적인 문제점을 찾아주는데 도움이 되므로, 라이브러리를 사용하기 위해 지우는 것이 해결책은 아니라는 생각이 들었다.

2. StrictMode 버전의 custom Droppable를 사용한다.
react-beautiful-dnd의 issue에서 발견한 방법인데, Strict Mode에서도 동작하는 custom Droppable을 추가하여 사용하는 방법이다. (해당 issue 보기)

react-beautiful-dnd의 현재 최신 버전은 v13.1인데, 활발하게 업데이트가 이뤄지는 프로젝트가 아니므로 리액트 18 Strict Mode를 지원하는 버전 15가 업데이트되기 전에는 이 커스텀 Droppable을 사용하는 것이 최선의 해결책으로 보인다.

애니메이션

framer motion

애니메이션과 제스처를 위한 라이브러리

npm install framer motion
import { motion } from "framer-motion"

공식문서의 사용법
버전이 맞지 않을 시 Failed to compile이라는 에러가 뜬다.
리액트 #8.1영상 참고

미디어 플레이어

React Player

영상 요소로 플레이어를 구현할 때 사용하는 라이브러리
타입 정의 스크립트를 제공한다는 장점이 있어 채택

주의점

ReactPlayer는 Blob URL로 재생 구간 이동을 지원하지 않으므로 Static Path 방식을 권장

React | React-Player 라이브러리를 활용한 비디오 플레이어 커스텀 + 재생바 만들기

  • 해당 벨로그에 기본적인 사용법이 잘 나와있다.

특정 구간 재생

<ReactPlayer
  // @ts-ignore
  ref={playerRef}
  // @ts-ignore
  url={playList[playIndex].url + "#t=3,10"}
  playing
  controls
  muted
  progressInterval={1000}
  pip={true}
  width={'800px'}
  height={'500px'}
/>

“#t=3,10”을 추가함으로써 플레이어는 3초 지점에 영상이 재생되고 10초 지점에 영상이 멈추게 된다.

모킹 및 테스트

MSW(Mock Service Worker) 2.0

서비스 워커(Service Worker)를 사용하여 네트워크 호출을 가로채는 API 모킹(mocking) 라이브러리
이러한 API Mocking Library를 통해 프론트엔드 개발자는 백엔드 API가 개발되기 전에 프론트 자체에서 가짜 API를 통해 ui를 개발해 볼 수 있다.

2.0과 이전 버전은 사용법이 다르니 참고할 것
2.0 설치와 적용법
설치시 public 폴더가 생긴다.
get, post 요청 예시(handlers.ts)

import { http, HttpResponse } from "msw";

interface User {
  id: number;
  nickname: string;
  email: string;
  password: string;
}

const users: User[] = [
  {
    id: 1,
    nickname: "Bam",
    email: "rlaugs15@naver.com",
    password: "1234567",
  },
];

export const handlers = [
  // GET 요청
  http.get("/api/users", () => {
    return HttpResponse.json(users, {
      status: 200,
      headers: {
        "Content-Type": "application/json",
      },
    });
  }),

  // POST 요청
  http.post("/api/users", async ({ request }) => {
    //{ email, password }에 에러표시가 뜨지만 잘 동작한다.
    const { email, password } = await request.json();

    // users에서 email과 password가 일치하는 user 검색
    const user = users.find(
      (user) => user.email === email && user.password === password
    );

    // 사용자가 없으면 401 응답
    if (!user) {
      return HttpResponse.json({
        code: 401,
        message: "사용자가 존재하지 않습니다",
      }, { status: 401 });
    }

    // 사용자가 있으면 해당 사용자 응답
    return HttpResponse.json(user, { status: 200 });
  }),
];

유틸리티

uuid

npm i uuid
__UUID (Universally Unique Identifier)를 생성하기 위한 라이브러리__
주로 고유한 식별자를 생성할 때 사용되며, 파일명, 사용자 ID 등 고유해야 하는 데이터에 유용하게 쓰임.
```javascript
import { v4 as uuidv4 } from 'uuid';

const uniqueId = uuidv4();
console.log(uniqueId); // 고유한 UUID가 생성되어 출력된다.

주요 사용처

  • 파일 업로드 시 고유한 파일명을 생성하기 위해 사용
  • 데이터베이스에서 중복되지 않는 ID 생성
  • 분산 시스템에서 고유 식별자 생성

사용한 이유

프로젝트에서 업로드된 이미지 파일에 대해 고유한 파일명을 생성하여, 파일 이름이 중복되지 않도록 하기 위해 사용
이를 통해 서버에 저장되는 파일들이 고유하게 관리되며, 다른 파일과의 이름 충돌을 방지할 수 있다.
특히, 프로필 이미지 업로드와 같은 기능에서 매우 유용하다.

종류

원하는 타입에 따라 생성하는 방식이 조금씩 다른데, 일반적으로 5가지의 종류가 있다.

  • v1: 타임스탬프(시간) 기준
  • v2: 타입스탬프 + DCE 보안
  • v3: MD5 해시 기준
  • v4: 랜덤값 기반
  • v5: SHA-1 해시 기준

랜덤값 기반으로 생성되는 v4가 가장 많이 사용되고, 다음으로는 시간 기준인 v1이 많이 사용된다.

포맷

UUID는 128비트수로 32개의 16진수로 표현되며, 총 36개의 문자(32개 16진수 + 4개의 하이폰)으로 구성돼있다.

UUID 패턴 예시
8 - 4 - 4 - 4 - 12 (총 36개 문자)
abl8dj11-blz1-987s-piuz-8zb02898xl1d

중복 가능성

UUID로 표현할 수 있는 객체의 생성 개수는 340,282,366,920,938,463,463,374,607,431,768,211,456개라고 하는데, 쉼표 세는 것도 힘들만큼 어마어마한 숫자이다. 무려 10의 36제곱...

한 마디로 중복될 가능성은 아주 낮다

지도

카카오맵

호출 횟수

  • 지도 API: 하루에 최대 30만 회
  • 로컬 API: 하루에 최대 10만 회
  • 카카오 디벨로퍼스 통합 API: 월에 최대 300만 회

지도 API와 로컬 API

  • 지도 API: 시각적으로 지도를 보여주고 조작할 수 있는 기능 제공
    • 지도를 화면에 보여주는 역할
    • 예) 웹페이지에 지도를 띄우고, 특정 위치에 마커(핀)를 찍거나 길 안내를 표시
  • 로컬 API: 지도를 띄우기 전에 필요한 데이터(위치, 좌표, 주소)를 가져오는 기능 제공
    • 위치 정보를 검색하거나 좌표 변환, 주소 찾기 등의 데이터를 제공
    • 예) '서울역' 같은 키워드를 입력하면 해당 위치의 좌표와 정보를 반환

Kakao Map SDK 중심 좌표 갱신 문제와 해결 방법

문제

  • 지도를 이동한 후, 버튼을 처음 누를 때는 정상적으로 중심 좌표가 이동했으나, 두 번째부터는 버튼이 제대로 작동하지 않음
  • SDK 샘플 코드에서도 동일한 문제가 발생하며, JavaScript API에서는 정상 작동

    원인 분석
  • 컴포넌트 내부에서 관리하는 center 상태가 지도 이동 시 자동으로 갱신되지 않기 때문에 발생한 문제로 추정

    해결 방법
  1. Kakao Map의 지도 이동 이벤트를 감지하여 onCenterChanged prop에 콜백 함수를 등록
  2. 지도 중심 좌표 변경 시, 콜백 함수가 호출되어 center 상태를 갱신하도록 처리
  3. 이벤트가 너무 빈번하게 발생하는 문제를 해결하기 위해 lodash의 debounce 함수를 사용하여 500ms 동안 추가적인 감지가 없을 때만 상태를 갱신
  4. 타이머 초기화를 방지하기 위해 useMemodebounce 함수 래핑

주의점

  • 가게에 대한 상세보기는 제공하지 않는다. 카카오페이지로 리다이렉트 해주는 주소는 제공해준다.

검증

Zod

JavaScript와 TypeScript를 위한 유효성 검사 라이브러리
스키마를 정의하고, 데이터가 해당 스키마에 맞는지 검증하거나, 데이터를 타입 변환할 수 있다.

Zod의 특징

  • 스키마 기반: 데이터 구조와 유효성 검사를 하나의 스키마로 정의.
  • 타입스크립트 통합: 타입 정의와 유효성 검사를 동시에 처리.
  • 가벼움: 작은 크기와 직관적인 API.

Zod 예제

import { z } from "zod";

// 유효성 검사 스키마 정의
const userSchema = z.object({
  name: z.string().min(2, "이름은 최소 2글자 이상이어야 합니다."),
  age: z.number().min(0, "나이는 0 이상이어야 합니다."),
});

// 데이터 검증
const result = userSchema.safeParse({ name: "John", age: 25 });
console.log(result.success); // true

언제 사용해야 할까?

  • 타입스크립트를 사용하는 프로젝트: Zod를 활용하면 타입 안정성을 크게 높일 수 있다.
  • 유효성 검사가 복잡한 폼: Zod의 풍부한 검증 기능을 활용해 직관적으로 폼 검증을 작성할 수 있다.
  • 폼 상태 관리와 성능을 중요시할 때: React Hook Form과 결합하면 간단한 코드로 효율적인 폼 상태 관리를 구현할 수 있다.

참고해야할 사이트

validator

npm i validator
npm i @types/validator

문자열 검증 및 살균(sanitization)을 위한 라이브러리
예를 들어, 이메일 주소가 유효한 형식인지, 문자열이 특정 형식에 맞는지 확인할 수 있다.

전화번호 유효성 검사 예시

"use server";

import { z } from "zod";
import validator from "validator";

// validator 라이브러리를 사용하여 전화번호 유효성 검사를 한다.
const phoneSchema = z
  .string()
  .trim()
  .refine(
    (phone) => validator.isMobilePhone(phone, "ko-KR"),
    "Wrong phone format"
  );

export async function smsLogIn(prevState: any, formData: FormData) {
  // input에 입력한 전화번호 값을 가져온다.
  const phone = formData.get("phone");
}

//zod와 같이 사용할 경우, "ko-KR"은 010
export const phoneSchema = z
  .string()
  .trim()
  .refine((phone) => validator.isMobilePhone(phone, "ko-KR"));

인증 및 세션 관리

Iron Session

안전하고 무상태인 쿠키 기반의 세션 라이브러리

  • 특징
  • 서버리스 환경에 적합하다.
    • 세션 데이터를 쿠키에 저장하여 별도의 서버측 저장소 필요 없음
  • 사용자 패스워드가 없어도 안전하게 암호화가 가능하다.
  • 미들웨어 하나로 쉽게 세션 기능을 추가할 수 있어서 러닝커브가 작다.

참고하면 좋은 블로그

추후 사용해볼 예정

es-hangul

npm install es-hangul

es-hangul
한글을 다루는 제품을 개발할 때, 초성 검색, 정확한 조사 붙이기와 같은 작업을 수행
그 외로 초성, 중성, 종성 등의 한글을 분리하거나 결합해야 하는 경우도 있는데 es-hangul은 이렇게 비즈니스에서 반복적으로 발생하는 한글 관련한 기능을 쉽고 빠르게 구현

react-slick

npm i react-slick

react-slick은 react에서 슬라이드를 손쉽게 구현하도록 도와주는 라이브러리

react-slick 사용방법, 커스텀 방법

npm i react-image-file-resizer

이미지 파일을 리사이징(크기 조정)할 수 있도록 도와주는 라이브러리
이미지를 업로드할 때 파일 크기를 줄이거나 원하는 크기로 조정하고 싶을 때 유용하다. 특히 이미지 크기를 줄여 업로드 속도를 개선하거나 저장 공간을 절약할 때 사용한다.

  • 주요기능
    • 이미지 리사이즈: 이미지 파일의 크기(가로, 세로)를 지정해 조정할 수 있다.
    • 포맷 변경: JPEG, PNG, WebP와 같은 다양한 이미지 포맷으로 변환할 수 있다.
    • 압축: 압축 품질을 설정해 이미지의 용량을 줄일 수 있다.
    • Base64 지원: 리사이즈된 이미지를 Base64 형식으로 반환할 수 있어 API 요청에 포함하기 편리하다.

react-image-file-resizer를 사용해 이미지를 리사이즈하고 Base64로 변환하는 예시

[React] 파이어베이스 프로필 이미지 용량 최적화

  • 이미지의 확장자를 webp로 변경하면 파일의 크기가 상당히 줄어든다.
profile
기록하자

0개의 댓글

관련 채용 정보