Calling actions outside a React event handler in pre React 18

김동현·2026년 3월 4일

zustand 공식문서 번역

목록 보기
10/19

안녕하세요! 프론트엔드 개발의 길로 오신 것을 환영합니다. 멘토로서 여러분이 Zustand를 완벽하게 소화할 수 있도록 도와드릴게요.

오늘은 Zustand 공식 문서 중 "React 18 이전 버전에서 React 이벤트 핸들러 외부에서 액션 호출하기" 부분을 함께 살펴보겠습니다. 원본 내용을 빠짐없이 번역하면서, 여러분이 실무에서 마주칠 수 있는 상황에 빗대어 쉽게 이해할 수 있도록 보충 설명과 팁도 팍팍 넣어드릴게요!


React 18 이전 버전에서 React 이벤트 핸들러 외부에서 액션 호출하기 (Calling actions outside a React event handler in pre React 18)

React는 이벤트 핸들러(event handler) 외부에서 setState가 호출될 경우 이를 동기적(synchronously)으로 처리합니다. 그렇기 때문에 이벤트 핸들러 밖에서 상태를 업데이트하게 되면, React가 컴포넌트들을 강제로 동기적으로 업데이트하도록 만듭니다. 따라서, 이 경우 좀비 차일드(zombie-child) 효과를 마주칠 위험이 존재하게 되죠.

이 문제를 해결하기 위해서는, 다음과 같이 액션(action)을 unstable_batchedUpdates로 감싸주어야 합니다:

import { unstable_batchedUpdates } from 'react-dom' // or 'react-native'

const useFishStore = create((set) => ({
  fishes: 0,
  increaseFishes: () => set((prev) => ({ fishes: prev.fishes + 1 })),
}))

const nonReactCallback = () => {
  unstable_batchedUpdates(() => {
    useFishStore.getState().increaseFishes()
  })
}

더 자세한 내용: https://github.com/pmndrs/zustand/issues/302


이 페이지 수정하기 (Edit this page)

이전 (Previous): URL로 상태 연결하기 (Connect to state with URL)
다음 (Next): 초보자를 위한 TypeScript 가이드 (Beginner TypeScript Guide)


👨‍🏫 강사의 보충 설명 시간!

공식 문서의 내용이 조금 짧아서 "갑자기 무슨 소리지?" 하셨을 수도 있어요. 제가 조금 더 풀어서 설명해 드릴게요.

1. '좀비 차일드(Zombie-child)' 효과란 무엇인가요?
부모 컴포넌트와 자식 컴포넌트가 모두 동일한 전역 상태(Zustand 스토어)를 바라보고 있다고 가정해 볼게요. 상태가 변경되어 부모 컴포넌트가 자식 컴포넌트를 화면에서 지워버리려고(언마운트) 하는 상황입니다. 그런데 자식 컴포넌트가 부모보다 먼저 상태 업데이트를 알아채고, 이미 사라졌어야 할 데이터나 props를 가지고 렌더링을 시도하다가 앱이 에러를 뿜으며 죽어버리는 현상을 말해요. 죽어야 할 자식이 죽지 않고 렌더링을 시도한다고 해서 '좀비'라는 섬뜩한 이름이 붙었답니다.

2. 왜 React 18 '이전' 버전이라고 콕 짚어서 말할까요?
React 18부터는 '자동 배칭(Automatic Batching)'이라는 아주 훌륭한 기능이 도입되었어요. 그래서 setTimeout, Promise, fetch 같은 비동기 함수나 일반 콜백 등 이벤트 핸들러 밖에서 상태를 여러 번 변경해도, React가 알아서 렌더링을 한 번에 묶어서(Batching) 처리해 줍니다. 따라서 React 18 이상 환경에서는 위 문서에서 말하는 에러를 만날 일이 거의 없게 해결된 것이죠!

💡 강사의 실무 밀착 팁!

실무에 나가시면 최신 React 18만 만지는 게 아니라, 예전에 만들어진 React 16, 17 버전의 레거시 프로젝트를 유지보수할 일이 꽤 많습니다.

이때, 버튼의 onClick 같은 React 합성 이벤트 안에서는 상태를 업데이트해도 괜찮은데, setTimeout, setInterval 안에서 Zustand 상태를 바꾸거나, 혹은 서버에서 API 데이터를 axiosfetch로 받아온 직후 .then() 안에서 상태를 변경할 때 이 '좀비 차일드 에러'가 기습적으로 출몰합니다!

"어? 서버 통신만 끝나면 화면이 왜 하얗게 죽지?" 싶을 때, 당황하지 마시고 이 unstable_batchedUpdates를 떠올려주세요. 비동기 콜백 안에서 상태를 바꾸는 로직을 저 함수로 싹 감싸주기만 하면 마법처럼 에러가 사라질 거예요. (함수 이름에 unstable_이 붙어있어서 쓰면 큰일 날 것 같지만, React 17 시절에는 아주 흔하게 쓰던 안정적인(?) 구세주 같은 녀석이랍니다.)


자, 오늘 배운 내용 어떠셨나요? 좀비 차일드라는 무시무시한 개념도 이제는 확실히 잡히셨길 바랍니다! 혹시 이 개념이나 다른 Zustand 기능에 대해 더 궁금한 점이 있다면 편하게 질문해주세요. 제가 더 설명해 드릴까요?

profile
프론트에_가까운_풀스택_개발자

0개의 댓글