기본 콘텐츠로 건너뛰기

라벨이 React인 게시물 표시

useEffect 로딩 상태와 Suspense는 무엇이 다르고 언제 써야 할까

useEffect 로딩 상태와 Suspense는 무엇이 다르고 언제 써야 할까 빠른 답 useEffect 방식은 요청 시작, 성공, 실패, 로딩 종료를 컴포넌트 안의 state로 직접 관리한다. Suspense 는 자식 트리가 아직 렌더링 준비를 끝내지 못했을 때 가장 가까운 fallback 을 보여주는 경계 모델이다. 일반 fetch 를 useEffect 안에서 호출하는 것만으로는 Suspense 가 동작하지 않는다. Suspense 를 쓰려면 fallback 위치, Error Boundary, 데이터 캐시나 프레임워크 지원 여부를 함께 봐야 한다. 목차 한눈에 비교 시간 흐름으로 이해하기 현재 React 기준에서 봐야 할 점 useEffect 방식이 맞는 상황 useEffect에서 자주 생기는 안티패턴 Suspense 방식이 맞는 상황 경계 배치와 리렌더링 흐름 선택 기준 한눈에 비교 상태 소유권 useEffect 방식은 isLoading , data , error 를 컴포넌트가 직접 가진다. Suspense 방식은 대기 UI 표시를 경계가 맡고, 데이터 준비 여부는 Suspense를 지원하는 데이터 소스가 담당한다. 데이터 흐름 useEffect 는 첫 렌더 이후 Effect에서 요청을 시작하고 응답을 state로 반영한다. Suspense 는 렌더링 중 값을 읽을 때 아직 준비되지 않았음을 React가 감지하고 경계로 빠진다. 리렌더링 useEffect 는 setState 가 일어나며 로딩 화면, 성공 화면, 실패 화면으로 다시 렌더링된다. Suspense 는 자식 트리 렌더링을 보류했다가 데이터가 준비되면 다시 렌더링을 시도한다. 에러 처리 useEffect 는 보통 error state와 조건부 렌더링으로 처리한다. Suspense 와 함께 쓰는 Promise 실패는 Error Boundary 또는 대체 값 설계가 필요하다. 적용 조건 useEffect 는 브라우저 API, 네트워크 요청, 외부 위젯처럼 컴포넌트 밖 시스템과 동...

React 동시성 이해하기: 입력은 즉시 반응하고 무거운 렌더링은 뒤로 미루는 법

React 동시성 이해하기: 입력은 즉시 반응하고 무거운 렌더링은 뒤로 미루는 법 빠른 답 현재 기준으로는 Concurrent Mode 라는 전역 모드를 켜는 방식보다, createRoot 기반의 동시 렌더링과 transition API를 필요한 업데이트에 적용하는 방식으로 이해하는 편이 정확합니다. 입력창 값처럼 즉시 반영되어야 하는 상태는 transition 으로 감싸지 않고, 그 입력에 따라 바뀌는 무거운 결과 영역만 낮은 우선순위로 미룹니다. 상태 업데이트를 직접 호출하는 위치라면 useTransition 또는 startTransition 을, 이미 전달받은 값의 화면 반영만 늦추고 싶다면 useDeferredValue 를 고려합니다. 동시성 API는 느린 계산을 빠르게 만드는 도구가 아니라, 사용자가 먼저 체감하는 렌더링이 막히지 않도록 우선순위를 나누는 도구입니다. 목차 시간 흐름으로 이해하기 흐름으로 보기 Concurrent Mode라는 표현이 헷갈리는 이유 설정 기준 잡기 데이터 흐름과 상태 소유권 useTransition과 startTransition을 쓰는 위치 useDeferredValue가 어울리는 경우 흔한 안티패턴 현재 기준의 마이그레이션 포인트 시간 흐름으로 이해하기 검색창에 글자를 입력하고 그 결과로 큰 목록이 다시 렌더링되는 상황을 기준으로 보면 React 동시성은 다음 흐름으로 동작합니다. 입력 발생 사용자가 검색어를 입력합니다. → 긴급 업데이트 입력창의 text 상태는 즉시 반영됩니다. → 전환 예약 결과 목록을 바꾸는 query 업데이트는 낮은 우선순위로 표시됩니다. → 렌더링 조정 결과 렌더링 중 새 입력이 들어오면 React가 기존 작업을 중단하거나 최신 값 기준으로 다시 시작할 수 있습니다. → 화면 커밋 렌더링이 완료된 결과만 실제 DOM에 반영됩니다. 여기서 중요한 구분은 입력 상태와 결과 상태를 같은 속도의 일로 보지 않는 것입니다. 사용자는 키를 눌렀을 때 글자가 바로 찍히는지를 먼저 ...

React 리렌더링을 줄이는 실전 기준: memo, useMemo, useCallback은 언제 써야 할까

React 리렌더링을 줄이는 실전 기준: memo, useMemo, useCallback은 언제 써야 할까 빠른 답 리렌더링은 React의 정상 동작입니다. 먼저 React DevTools Profiler나 Profiler API로 느린 컴포넌트와 상호작용을 확인하는 편이 좋습니다. memo 는 부모가 자주 렌더링되지만 자식의 props 가 자주 같게 유지되는 경우에 효과가 있습니다. useMemo 는 비싼 계산 결과를 캐시할 때, useCallback 은 함수 참조 변화가 자식 리렌더링이나 Effect 재실행으로 이어질 때 씁니다. 메모이제이션에도 비교 비용, 메모리 비용, 의존성 관리 비용이 있으므로 모든 값과 함수에 붙이는 방식은 대체로 이득이 작습니다. 목차 선택 기준 매트릭스 React 리렌더링 흐름 문제가 되는 리렌더링 현재 기준과 오래된 설명의 차이 상태 소유권부터 정리하기 자식 컴포넌트 리렌더링 줄이기 린트와 구성 기준 Profiler로 병목 확인하기 흔한 오해와 주의사항 선택 기준 매트릭스 상황 부모만 자주 바뀌고 자식 props 는 그대로라면 memo 로 자식 렌더링을 건너뛸 수 있습니다. 상황 큰 배열 필터링, 정렬, 집계처럼 렌더 중 계산이 무겁다면 useMemo 로 계산 결과를 재사용합니다. 상황 memo 로 감싼 자식에게 콜백을 넘기는데 함수 참조가 매번 바뀐다면 useCallback 을 고려합니다. 조건 객체, 배열, 함수가 매 렌더마다 새로 만들어진다면 props 형태를 줄이거나 참조를 안정화해야 memo 가 의미를 가집니다. 조건 입력값, hover, 모달 열림 같은 일시적 UI 상태가 너무 위에 있다면 메모이제이션보다 상태 위치 조정과 컴포넌트 분리가 먼저입니다. 상황 React Compiler를 도입한 환경이라면 수동 메모이제이션 필요성이 줄 수 있지만, 빌드 설정과 지원 범위를 먼저 확인해야 합니다. React 리렌더링 흐름 React 컴포넌트는 state , props , context 가 바뀌면 다시...

React Error Boundary로 화면 전체가 무너지는 오류 막기

React Error Boundary로 화면 전체가 무너지는 오류 막기 빠른 답 Error Boundary는 하위 컴포넌트의 렌더링, 생명주기, 생성자에서 발생한 오류를 잡아 fallback UI로 바꾼다. 이벤트 핸들러, 서버 사이드 렌더링, 일반 비동기 콜백의 오류는 자동으로 잡지 않는다. React에서 직접 Error Boundary를 만들 때는 현재도 클래스 API인 static getDerivedStateFromError 와 componentDidCatch 를 사용한다. 데이터 요청 실패는 요청 상태가 소유하고, Error Boundary는 렌더링 실패를 격리하는 역할로 두는 편이 읽기 쉽다. 목차 흐름으로 보기 데이터 흐름과 상태 소유권 잡는 오류와 잡지 못하는 오류 현재 React 기준과 마이그레이션 포인트 기본 Error Boundary 구현 경계 배치와 리렌더링 설계 라이브러리 패턴 디버깅 출력과 로그 설계 흔한 안티패턴 흐름으로 보기 흐름 다이어그램 React는 부모에서 자식 방향으로 데이터를 내려보내며 컴포넌트를 렌더링한다. 이때 하위 컴포넌트가 렌더링 중 예외를 던지면 React는 컴포넌트 트리의 부모 방향으로 올라가며 가장 가까운 Error Boundary를 찾는다. 경계를 찾으면 해당 하위 트리를 정상 UI로 계속 유지하지 않고 fallback UI로 교체한다. 이후 componentDidCatch 에서 오류 객체와 React 컴포넌트 스택을 로깅할 수 있다. 경계가 없다면 React는 깨진 UI를 남겨두지 않기 위해 루트 UI를 제거할 수 있고, 사용자는 흔히 말하는 하얀 화면을 보게 된다. 데이터 흐름과 상태 소유권 Error Boundary를 이해할 때 먼저 나눠야 할 것은 “예상 가능한 상태”와 “렌더링이 깨진 상태”다. API 요청이 실패했거나 데이터가 아직 로딩 중인 상태는 애플리케이션의 정상적인 데이터 흐름 안에 있다. 이 상태는 데이터를 요청한 컴포넌트나 데이터 패칭 계층이 소유하는 편이 자연스럽다...