전체 글

전체 글

    [Husky] Git Hooks 설정을 통한 커밋 전 코드 포맷팅 자동 적용하기 (Lint-Staged)

    GitHub에서 다른 사람의 프로젝트를 보다가 .husky 폴더가 있는 걸 보고 이건 뭘까?하고 찾아보게 되었다. 찾아본 내용을 바탕으로 지금 작업 중인 프로젝트에도 적용해 보고, 그 과정을 정리해봤다. Husky는 Git Hooks 사용을 도와주는 라이브러리이다.  Git Hooks란 Git에서  어떤 이벤트가 생겼을 때 자동으로 특정 스크립트를 실행하도록 하는 기능이다. Husky를 사용하면 커밋 전, 푸쉬 전에 특정 동작을 수행할 수 있다. 이를 통해 주로 lint, prettier를 자동 적용하는 경우가 많다. 나도 개발하면서 lint, prettier을 제대로 적용하지 않은 파일을 그대로 커밋할 때가 많았다. 이후에 뒤늦게 ci/cd에서 오류를 발견하거나 포맷팅을 다시 해야 해서 번거로움을 겪었..

    [React] 라이브러리 없이 Toast 구현하기

    프로젝트에서 Toast 컴포넌트 구현을 맡게 되었다. Toast는 라이브러리로도 사용해 본 적이 없었는데 직접 구현하게 되어서 좋았다. 구현할 Toast의 조건 1. Context API를 이용하여 전역 관리 2. Toast Portal을 만들고 이 안에 Toast를 띄울 것! 3. useToast hook을 통해 팀원들이 사용하기 쉽도록 할 것 1. Toast 컴포넌트 스타일링 우리 팀은 위와 같이 6가지 형태의 toast를 상황에 맞게 사용하기로 하였다. 그래서 메시지를 필수 기본 요소로 두고, 메시지 옆의 아이콘 유무, 닫기 버튼의 유무, action 버튼의 유무에 따라 렌더링 할 요소와 스타일을 다르게 적용하기로 했다. // components/Toast/index.tsx import { X } ..

    [React] ios 환경에서 input, textarea 화면 확대 방지하기 (+ 웹 접근성)

    ios 환경에서 input, textarea를 터치하면 화면이 자동으로 확대되는 현상이 있다. 이를 방지하기 위한 세 가지 방법이 있다. 1. viewport 설정하기 다음과 같이 index.html의 viewport meta 태그에 maximum-scale=1.0, user-scalable=0을 추가한다. // index.html 가장 간단한 방법이며 나도 이전까지 많이 사용하던 방법이다. 그런데 이 설정을 추가하게 되면 웹 접근성에 좋지 않다는 걸 알게 되었다. 팀원 분이 lighthouse에서 수행한 접근성 검사에서 이런 결과가 나왔다. user-scalable을 막고 maximum-scale을 줄이는 게 사용자의 화면 확대를 막음으로써 접근성에 좋지 않다는 것이다. 하지만 저걸 설정한다고 해서 실..

    [React] useReducer

    팀 프로젝트를 하면서 useReducer에 대해 알게 되었다. React 공식 문서와 다른 분들의 글을 보면서 공부한 것을 정리해 본다. 정리 과정에서 타입스크립트도 적용해 보았다. useReducer를 사용하는 이유? useState는 작성해야 하는 코드의 양이 적어 상태 변경이 매우 간단할 때 읽기 쉽다. 하지만 컴포넌트가 커지고 상태 변경 로직이 복잡해지면 가독성이 떨어진다. 또한 많은 이벤트 핸들러에 여러 상태 변경이 분산되면 가독성도 좋지 않을뿐더러, 상태 변경 로직을 관리하는 것이 어려워진다. 이러한 경우 useReducer를 사용하면 상태 변경 로직을 reducer 내부로 옮겨 이벤트 핸들러와 상태 변경 로직을 완전히 분리하면서, 모든 상태 변경 로직을 한 곳에 통합시킬 수 있다. useRe..

    [React] React Router - RouterProvider, createBrowserRouter

    최근에 프로젝트를 진행하면서 팀원 분의 코드를 보고 내가 몰랐던 React Router 사용 방식이 있다는 걸 알았다. 그래서 React Router 공식 페이지를 참고하여 내용을 정리해 보았다. 내가 사용하고 있던 기존 방식 import { BrowserRouter } from "react-router-dom"; const root = ReactDOM.createRoot(document.getElementById("root") as HTMLElement); root.render( ); import { Routes, Route } from "react-router-dom"; import Layout from "@/components/Layout"; import Login from "@/pages/Logi..