적절한 추상화를 통해 Modal을 선언적으로 사용하기
·
문제 해결/리팩터링
선언적 프로그래밍이란?선언적 프로그래밍이란 무엇을 표현할지에 집중하고 어떻게 할지는 숨기는 개발 스타일이다.UI를 선언적으로 사용할 수 있도록 만들면 당장 몰라도 되는 디테일은 숨겨지고 핵심 정보가 들어나서 로직을 파악하기 쉬워진다. 인터페이스부터 생각하자리액트에서 간단한 alert 컴포넌트를 모달로 띄운다고 가정해보자. 사용처에서 UI 컴포넌트를 import하거나 만들고 isOpen과 같은 상태로 여닫기를 관리해줘야한다.이에 비해 브라우저 내장 Web API인 window.alert()의 사용 방법은 간단하고 선언적이다.alert("Hello world!");어디서나 메시지와 함께 alert 함수를 호출해주기만 하면 창을 띄워준다.이렇게 간단한 방식으로 리액트 컴포넌트도 띄울 수 있도록 만들어보자.co..
토글 버튼으로 theme 상태 변경하기 (feat. context API, 커스텀 훅)
·
문제 해결
기존에 styled-components의 ThemeProvider로 다크모드를 구현하고 있었는데, 토글 버튼에 setTheme 함수를 직접 전달해주다 보니 props drilling이 우려되고 추상화도 잘 되지 않아서 코드가 지저분해 보였기 때문에 리팩터링을 하려고 마음먹었다. theme의 상태를 관리하기 위해서 보통 전역 상태 라이브러리를 많이 사용하지만, 현재 개인 프로젝트에서 전역으로 관리할 상태가 theme 밖에 없어서 패키지를 설치하지 않고 가볍게 사용할 수 있는 걸 찾으려고 했다. 처음엔 URI 쿼리 스트링으로 상태를 관리하는 방법을 생각했다. 하지만 유저가 URI를 직접 수정할 수 있어서 예기치 않은 변경이 발생할 수 있고, URI가 변경될 때마다 브라우저 히스토리가 쌓여서 히스토리가 불필요..
Storybook에서 styled-components의 ThemeProvider 사용하기
·
문제 해결
❗️ 문제 yarn start를 했을 때는 theme이 적용된 컴포넌트가 잘 보이는데 storybook에서는 오류가 나면서 프리뷰가 나오지 않는 문제가 있었다. ${({ theme }) => css` color: ${theme.COLOR.TEXT.WHITE}; 처음엔 theme을 잘못 설정한 줄 알고 style 쪽 코드를 계속 수정했지만 해결되지 않았다. 🔎 원인 생각해 보니 dev server에서는 잘 나오기 때문에 style 쪽 문제는 아니었다. App.tsx에서는 ThemeProvider가 사용되고 있어서 dev server에서는 문제가 없었지만, storybook에 ThemeProvider를 따로 적용해 주지 않아서 발생한 오류였다. 컴포넌트만 공유하고 번들링부터 아예 따로 동작하기 때문에 필요한..
CRA 없이 webpack.config 작성하기
·
문제 해결
개인 프로젝트는 CRA 없이 웹팩을 직접 설정해서 진행하기로 했습니다. 📍웹팩의 핵심 개념 Entry: 웹팩을 실행할 대상 파일. 진입점 Output: 웹팩의 결과물에 대한 정보를 입력하는 속성. 일반적으로 filename과 path를 정의 Loader: CSS, 이미지와 같은 비 자바스크립트 파일을 웹팩이 인식할 수 있게 추가한다. 로더는 오른쪽에서 왼쪽 순으로 적용 Plugin: 웹팩의 기본적인 동작에 추가적인 기능을 제공한다. 로더는 파일을 해석하고 변환하는 과정에 관여하는 반면, 플러그인은 해당 결과물의 형태를 바꾸는 역할을 한다. Resolve: 웹팩에서 모듈을 해석할 때 어떤 확장자를 사용할지를 설정한다. resolve 옵션을 설정하면, import나 require 등으로 모듈을 불러올 때 해..
TypeScript 리팩터링 - type predicates + type narrowing
·
문제 해결/리팩터링
❗️ 문제 로그인과 회원가입 페이지의 뷰 컴포넌트를 하나로 사용하고 있었기 때문에 폼이 submit 됐을 때 어떤 페이지에서 렌더링 된 건지에 따라서 서로 다른 API 전송 함수를 서로 다른 props로 보내서 트리거했었다. // submit 되면 실행되는 함수. const onValid = (data) => { if (signUp) { handleSignUp(data); } else { handleLogIn(data); } }; 하지만 하나의 props로 통일해도 된다고 판단했다. // submit 되면 실행되는 함수. const onValid = (data: AuthFormValues) => { handleSubmitForm(data); }; 인자에 대한 타입은 다음과 같다. export interf..
TypeScript 리팩터링 - useRef 타입 오버로딩 파악하고 사용하기
·
문제 해결/리팩터링
❗️ 문제 로그인, 회원가입 폼에 애니메이션을 트리거하기 위해서 만든 useRef에 타입을 줘야 했다. 본질적으로 useRef는 .current 프로퍼티에 변경 가능한 값을 담고 있는 “상자”와 같다. 처음엔 이런 형태로 타입을 부여했었다. const inputRef = useRef(null); 그런데 인풋의 ref 속성으로 부여된 useRef 값의 current에 접근할 수 없는 문제가 생겨서 그 이유를 살펴보았다. 🔎 원인 useRef 훅은 3개의 정의가 오버로딩되어 있다. 1. useRef(initialValue: T): MutableRefObject; 인자의 타입과 제네릭의 타입이 T로 일치하는 경우, MutableRefObject를 반환한다. MutableRefObject의 경우, 이름에서도 볼..