Blog
useState로 상태를 관리하다가 불편해지기 시작한 지점
문제를 느낀 지점#
게시글 목록 페이지에서
필터와 정렬 상태를 useState로 관리했다.
페이지 내부에서는 문제가 없었지만,
새로고침이나 페이지 이동 이후 다시 돌아오면
설정했던 필터가 모두 초기화됐다.
특히
목록 → 상세 → 목록
이 흐름에서 매번 상태가 풀리면서,
사용자의 탐색 맥락이 유지되지 않는 문제가 반복됐다.
브라우저의 뒤로가기에서도
같은 현상이 발생했다.
URL은 이전 페이지로 돌아왔지만,
화면에 보이는 상태는 초기 상태였다.
이때부터
페이지는 정상적으로 이동했지만
UI는 과거 상태를 기억하지 못한다는 어색함이 느껴졌다.
원인#
문제의 원인은 단순했다.
useState로 관리한 상태는
컴포넌트의 생명주기에 종속된다.
페이지 이동이나 새로고침이 발생하면
컴포넌트는 다시 마운트되고,
상태 역시 초기값으로 재생성된다.
또 하나의 원인은
이 상태들이 URL이나 브라우저 히스토리와 전혀 연결돼 있지 않았다는 점이다.
즉,
- 브라우저는 이전 페이지로 돌아왔지만
- React는 처음 보는 화면처럼 렌더링했다
이 불일치가
"동작은 맞지만 경험은 어색한" 화면을 만들고 있었다.
해결 방향#
이후부터는
상태의 성격에 따라 관리 위치를 분리하기 시작했다.
쿼리 스트링#
필터, 정렬처럼
목록의 조건을 결정하는 상태는
URL에 포함시키는 방식으로 옮겼다.
- 새로고침 이후에도 상태 유지
- 뒤로가기와 자연스럽게 동기화
- 링크 공유 시 동일한 화면 재현 가능
이 상태들은
페이지 내부 상태라기보다
페이지의 조건에 가까웠다.
로컬 / 세션 스토리지#
일시적으로 유지되면 되는 상태는
브라우저 스토리지를 활용했다.
- 세션 동안만 유지되면 되는 경우
- URL에 노출할 필요는 없는 경우
이 방식은
사용자 경험을 유지하면서도
구조를 크게 바꾸지 않는 선택이었다.
정리#
모든 상태를 useState로 관리하는 것은
간단하지만, 항상 적절하지는 않다.
상태의 위치와 생명주기를 결정하는 것이
문제를 줄이는 첫 단계였다.
관련 게시글
8개
JSX가 무엇인지 정리하기
JSX가 무엇인지 개념부터 정리합니다. HTML처럼 보이지만 JavaScript 문법 확장이라는 점과, 빌드 과정에서 함수 호출로 변환되는 구조를 중심으로 설명합니다.
메모이제이션이란 무엇인가
메모이제이션이 무엇인지 개념부터 정리합니다. 계산 최적화 기법으로서의 메모이제이션이 어떤 전제에서 성립하는지, 그리고 언제 의미를 가지는지를 중심으로 설명합니다
자주 사용하는 리액트 훅 (2)
React에서 구조와 렌더링 타이밍을 다루기 시작하면서 사용하게 된 훅들을 정리합니다. useLayoutEffect, useContext, 커스텀 훅이 어떤 상황에서 유용했는지를 중심으로 기록합니다.
자주 사용하는 리액트 훅 (1)
React에서 가장 자주 사용하는 훅인 useState, useEffect, useRef를 정리합니다. 각 훅이 무엇을 위한 도구인지와 어떤 상황에서 유용한지를 중심으로 설명합니다.
props drilling이 생겼던 구조와 당시 선택
React에서 상태를 상위로 끌어올리면서 발생한 props drilling 구조를 정리합니다. 중간 컴포넌트가 props를 전달만 하게 된 문제와, 그 시점에서 Context API를 선택지로 고려하게 된 이유를 기록합니다.
리액트에서 key를 사용하는 이유
React에서 리스트를 렌더링할 때 key가 왜 필수인지 정리합니다. React의 렌더링 방식과 index를 key로 사용할 때 발생하는 문제를 중심으로, 안정적인 key를 선택하는 기준을 기록합니다.
clsx 다음에 tw-merge가 필요한 이유
Tailwind CSS에서 clsx로 조건부 클래스를 합친 뒤, tw-merge로 클래스 충돌을 정리하는 이유를 정리합니다. clsx와 tw-merge를 함께 사용하는 흐름과 cn 유틸 패턴을 설명합니다.
clsx / classnames를 언제, 왜 사용하는가
Tailwind CSS를 사용하며 조건부 클래스가 늘어날 때, clsx와 classnames를 언제, 왜 사용하게 되는지 정리합니다. 문자열 기반 클래스 처리의 한계와 정리 기준을 학습 관점에서 설명합니다.