Develope/React 9

Zustand를 로컬 상태 대신 써도 되는 순간은 언제일까

React에서 상태를 다룰 때 가장 먼저 떠오르는 도구는 보통 useState다.컴포넌트 안에서 바로 선언할 수 있고, 이해하기도 쉽다.반면 Zustand는 전역 상태 관리 도구라는 인식이 강하다.그래서 상태를 만들 때 종종 이런 고민이 생긴다."이건 그냥 useState로 두는 게 맞을까, 아니면 Zustand로 빼는 게 맞을까?"처음에는 단순한 모달 상태 하나였는데,조금 지나면 여러 컴포넌트에서 참조하고,라우트가 바뀌어도 유지하고 싶고,다른 액션과 함께 제어해야 하는 순간이 온다.바로 이때 로컬 상태와 전역 상태의 경계가 헷갈리기 시작한다.이번 글에서는 Zustand를 로컬 상태 대신 써도 되는 순간이 언제인지,그리고 반대로 그냥 useState로 두는 편이 더 좋은 순간은 언제인지 정리해보려고 한다..

Develope/React 2026.04.13

Zustand에서 전역 상태와 서버 상태를 어떻게 구분할까?

Zustand를 쓰기 시작하면 상태를 한곳에 모아두는 경험이 꽤 편하다.컴포넌트 어디서든 꺼내 쓸 수 있고, API도 단순해서 빠르게 전역 상태를 만들 수 있다.그래서 어느 순간 이런 고민이 생긴다."이 값도 store에 넣어도 될까?"예를 들어 아래 같은 값들이다.로그인한 사용자 정보상품 목록 API 응답장바구니 개수현재 열려 있는 모달 상태검색 결과로딩 상태겉으로 보면 모두 "여러 컴포넌트에서 같이 써야 하는 값"처럼 보인다.하지만 이들을 전부 같은 종류의 상태로 보면 점점 구조가 꼬이기 시작한다.이번 글에서는 Zustand를 사용할 때 자주 헷갈리는 전역 상태와 서버 상태의 차이를 정리하고,어떤 값은 store에 두는 것이 맞고 어떤 값은 서버 상태 도구로 관리하는 편이 좋은지 기준을 정리해보려고 ..

Develope/React 2026.04.13

Zustand store를 너무 크게 만들면 어떤 문제가 생길까? slice 패턴으로 나누는 기준

Zustand는 간단하다.처음 사용할 때는 store 하나를 만들고, 그 안에 상태와 액션을 모두 넣는 방식이 꽤 자연스럽다.예를 들어 아래 같은 코드는 시작하기에 충분히 편하다.import { create } from "zustand";interface AppState { user: { id: string; name: string } | null; theme: "light" | "dark"; notifications: string[]; cart: { id: number; name: string; quantity: number }[]; isLoading: boolean; setUser: (user: { id: string; name: string } | null) => void; setThe..

Develope/React 2026.04.13

Zustand에서 shallow 비교는 언제 필요할까? selector와 함께 이해하기

이전 글에서 Zustand selector는 언제 쓰는 것이 좋은지 정리했다.그다음 단계에서 자주 같이 등장하는 키워드가 바로 shallow다.selector를 찾아보다 보면 아래 같은 코드도 자주 보게 된다.import { shallow } from "zustand/shallow";const { bears, honey } = useBearStore( (state) => ({ bears: state.bears, honey: state.honey, }), shallow);처음 보면 "selector를 쓸 때는 shallow도 같이 써야 하나?"라는 생각이 들 수 있다.하지만 실제로는 그렇지 않다.shallow는 항상 필요한 옵션이 아니라, 여러 값을 묶어서 선택할 때 생기는 비교 문제를 완..

Develope/React 2026.04.11

Zustand Selector는 언제 써야 할까? 성능과 가독성 사이에서 판단하는 기준

Zustand를 사용하다 보면 자연스럽게 selector를 접하게 된다.공식 예제나 여러 글에서 아래와 같은 코드를 자주 볼 수 있다.const bears = useBearStore((state) => state.bears);처음 보면 단순히 "원하는 값만 꺼내오는 문법" 정도로 느껴질 수 있다.하지만 실제로는 렌더링 범위를 줄이고, 컴포넌트의 관심사를 분리하고, 상태 구독 범위를 명확하게 만든다는 점에서 꽤 중요한 역할을 한다.다만 여기서 한 가지 고민이 생긴다.selector는 항상 써야 할까?아니면 필요할 때만 선택적으로 써야 할까?이번 글에서는 Zustand selector를 "무조건 써야 하는 패턴"으로 보기보다, 언제 도입하면 좋고 언제는 굳이 복잡도를 늘릴 필요가 없는지에 집중해서 정리해보려..

Develope/React 2026.04.09

CRA에서 Vite + SSR로 마이그레이션하며 겪은 문제와 해결 과정

1. 문제 상황기존 서비스는 CRA(Create React App) 기반의 CSR 구조로 운영되고 있었다.초기에는 빠른 개발과 단순한 구조 덕분에 큰 문제가 없었지만, 서비스가 성장하면서 점점 한계가 드러났다.특히 다음과 같은 문제가 반복적으로 발생했다.초기 로딩 속도 지연 (FCP/LCP 저하)SEO 대응의 어려움번들 사이즈 증가Webpack 기반 빌드 속도 저하단순한 최적화로는 해결이 어려웠고,결국 렌더링 방식 자체를 바꾸는 방향을 검토하게 되었다.2. 기존 구조의 한계2.1 CSR 구조의 구조적 문제CRA 기반 CSR에서는 모든 렌더링이 클라이언트에서 이루어진다.이로 인해:HTML은 비어있는 상태로 전달됨JS 로딩 이후에야 화면 렌더링초기 사용자 경험 저하특히 네트워크 환경이 좋지 않을수록 문제는 ..

Develope/React 2026.04.05

Recoil - Cannot update a component (`Batcher`) while rendering a different component 에러에 대하여

Recoil 상태 관리 라이브러리 적용해보는 중에 해당 에러가 발생하였습니다. Cannot update a component (`Batcher`) while rendering a different component ...recoil에서 Batcher라 불리는 컴포넌트를 통하여 RecoilRoot 컴포넌트 내에 있는 값들을 대체하도록 되어있는데, 이러한 내용이 react v16.13.0부터 anti-pattern으로 warning 메시지를 출력하도록 설정되었다는 내용입니다. 2020-07-08 현재까지도 해당 경고 메시지가 발생하며, 해당 메시지가 불편할 경우 v16.12으로 downgrading하여 사용해야할 것 같습니다. 2020-07-02 현재 해당 이슈는 github에 이슈에 보고되어져 있으며, 좀..

Develope/React 2020.07.02

[React]반복문으로 컴포넌트 렌더링시 고유값을 부여하는 이유

Key 속성에 따른 재사용성 Each child in an array should have a unique "key" prop. Check the render method of Component. List 형태 등의 데이터를 통해 컴포넌트를 구성하다 보면 위의 경고 메시지를 보신 적이 있을 것입니다. 해당 경고 메시지는 각각의 컴포넌트에 고유 'key'값을 가져야 하기 때문에 컴포넌트를 확인해달라는 내용으로써, 컴포넌트에 key 속성 값을 고윳값으로 가지도록 수정한다면 해당 경고 메시지를 해결할 수 있습니다. key 속성에 고유의 값을 부여하면 이 데이터는 어떻게 쓰일까요? 부여받은 key를 통해 기존 트리와 이후 트리의 자식들이 일치하는지 확인하는 값으로 사용하고 있다고 합니다. Duke Villano..

Develope/React 2020.06.23

CRA(Create React App) 서비스워커(ServiceWorker) 커스텀

개요 CRA(Create React App)를 통하여 생성된 프로젝트는 서비스 워커(serviceWorker) 기능을 제공합니다. CRA에서 기본적으로 제공되는 service-worker.js파일은 아래와 같습니다. CRA에서 서비스워커를 재구성하는 방법은 여러 가지 방법이 있겠지만 workbox를 사용하여 서비스워커를 재구성하는 방법을 설명하고자 합니다. 환경 구성 프로젝트 생성 CRA를 사용하여 프로젝트를 생성합니다. npx create-react-app rca-workbox-customize-deploy 모듈 설치 workbox-build, npm-run-all 모듈을 설치합니다. npm install --save-dev workbox-build npm-run-all workbox-build 모듈 ..

Develope/React 2020.06.13