Develop/React

    Zustand 사용해 보기 (+ Redux와 비교)

    Redux 외에도 사람들이 많이 사용하는 상태 관리 라이브러리를 사용해보고 싶어서 Zustand 공식 문서를 읽어보고 사용해 봤다. Recoil과 Zustand 중에 고민했는데 Recoil은 페이스북에서 손을 놓은 것인지... 마지막 업데이트로부터 시간이 많이 지나 여러 사람들이 다른 라이브러리로 마이그레이션 하는 것을 보고 Zustand를 선택했다.   'Zustand'는 독일어로 '상태'라는 뜻을 가진다. 공식 페이지에서는 Zustand를 작고, 빠르고, 확장 가능한 기본적인 상태 관리 솔루션이라고 소개하고 있다.  Zustand는 hooks를 기반으로 하는 사용하기 쉬운 API를 제공한다. 보일러플레이트 코드가 많지 않고 단순화된 Flux 원칙을 바탕으로 한다.   설치npm i zustand   ..

    [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..

    [React] Pagination 구현하기

    프로젝트를 하면서 Pagination이 필요해 구현해 보기로 했다. 찾아보니 라이브러리도 여러 개 있던데 머리도 쓸 겸 그냥 직접 구현해 보기로 했다. Pagination의 동작 구조 전반적인 동작 구조는 네이버 블로그에 있는 Pagination을 따라 했다. 1. 숫자를 누르면 페이지가 이동한다. (URL의 query string 값이 바뀐다.) 2. 현재 페이지에는 active 디자인을 적용해 준다. 3. 이전과 다음 글자는 이전 또는 다음 페이지가 존재할 경우에만 보이도록 한다. 4. 이전 버튼을 누르면 바로 이전의 end 지점(start 지점 + 보여줄 페이지수 - 1)로 이동한다. 5. 다음 버튼을 누르면 바로 다음의 start 지점으로 이동한다. 6. 각 숫자 및 글자는 Link 태그(a 태그..

    [React] CSS 없이 간단한 별점 기능(Star Rating) 구현하기

    책 후기를 작성하는 웹페이지를 만들면서 별점 기능이 필요해 구현해 보았다. 구글링을 해보니 굉장히 다양한 방법으로 구현한 다양한 유형의 별점 기능들이 있었다. 0.5점(별 반 개) 단위로 별점을 매기기도 하고, hover를 하면 색이 변하게 한다거나 드래그를 해서 별점을 매기는 방법도 있었다. 그러나 대부분의 별점 기능들이 꽉 찬 별 모양(★)을 점수에 따라 색깔만 바꾸는 형식으로 이루어졌다. 나는 꽉 찬 별 모양과 테두리만 있는 별 모양(☆)을 함께 사용하고 싶었기 때문에 다른 방식으로 별점 기능을 구현했다. 별 모양을 그리기 위해 react-icons에서 위의 두 아이콘을 사용하였다. https://react-icons.github.io/react-icons/search?q=pistar hover나 ..

    [React] textarea 입력에 따라 높이 자동 조절하기

    CSS textarea { all: unset; box-sizing: border-box; -webkit-appearance: none; -moz-appearance: none; appearance: none; overflow: hidden; width: 100%; height: 1.7em; line-height: 1.7em; } 컴포넌트 import { useRef, useState } from "react"; export default function Write() { const textareaRef = useRef(null); const [text, setText] = useState(""); const onChange = (e: React.ChangeEvent) => { setText(e.curr..