토스는 어떻게 광고 속에 게임을 넣었을까
토스가 광고 시스템을 자체 구축하면서 서드파티 SDK 대신 국제 광고 표준 MRAID를 직접 구현해 플레이어블 광고(앱 설치 전 게임 체험)를 지원한 과정이다. mraid.js 브릿지, 5중 렌더링 완료 신호, 보안 중심 설계, 앱 심사 없는 즉시 배포를 동시에 달성했다.
요약 이어보기Redux에서 서버 상태(Server State)를 관리할 때의 한계를 짚고, React Query와 SWR이 어떻게 이 문제를 해결하는지 코드 예시와 함께 비교한다. SWR에서 React Query로 마이그레이션한 경험을 바탕으로 두 라이브러리의 실질적인 차이점을 정리한다.
핵심 포인트 - 상태 3분류: Local State(컴포넌트 내부), Global State(전역 스토어), Server State(서버 데이터). 기존 Redux는 이 셋을 혼재해서 관리 - Redux의 서버 상태 관리 문제: redux-thunk(액션 형태 변형), redux-saga(장황한 보일러플레이트), 폴링 로직 직접 구현, 동일 API 중복 호출, 스토어 비대화 - 핵심 가치: data fetching 라이브러리 도입으로 상태관리에서 비동기 로직 분리 → 관심사 분리 + 선언적 프로그래밍 - 공통 핵심 기능: 캐싱, 자동 리페칭(포커스/인터벌), 로딩/에러 상태 자동 관리, 중복 요청 제거, 낙관적 업데이트 - SWR → React Query 전환: 대부분 함수명만 대체하면 됨. 단, 일부 동작 방식 차이 있음 - 팀 내 이유: 두 프로젝트가 각각 SWR/React Query 사용 → 컨텍스트 스위칭 비용 감소 위해 React Query로 통일
상세 정리 - redux-thunk 문제: 액션이 순수 객체 형태를 잃고 함수가 됨. 상태 업데이트 시점 불명확 - redux-saga 문제: call/put/takeEvery/all 등 레이어가 깊어 비동기 흐름 추적 어려움. 코드 양 대폭 증가 - 폴링 문제: 다른 사용자의 변경사항(좋아요 등)을 실시간 반영하려면 setInterval 등으로 직접 폴링 구현 필요 - SWR 기본 패턴: const { data, error } = useSWR('/api/user', fetcher) — 캐시 키 + fetcher 함수 - React Query 기본 패턴: const { data, error } = useQuery(['user'], fetchUser) — queryKey 배열 + queryFn - 공통 장점: 같은 키로 여러 컴포넌트가 데이터 요청해도 실제 API 호출은 1회 (중복 제거) - 차이점: React Query는 DevTools, 무한 스크롤(useInfiniteQuery), mutation 관리(useMutation) 등 더 풍부한 기능 제공. SWR은 더 가볍고 단순 - 낙관적 업데이트: 서버 응답 전에 UI 먼저 변경. 실패 시 롤백. 두 라이브러리 모두 지원
왜 읽나: Redux의 비동기 상태관리 한계를 실제 코드로 확인하고, React Query와 SWR의 개념·API·실제 마이그레이션 경험을 한 번에 파악해 서버 상태관리 라이브러리 선택 기준을 세울 수 있다.
토스가 광고 시스템을 자체 구축하면서 서드파티 SDK 대신 국제 광고 표준 MRAID를 직접 구현해 플레이어블 광고(앱 설치 전 게임 체험)를 지원한 과정이다. mraid.js 브릿지, 5중 렌더링 완료 신호, 보안 중심 설계, 앱 심사 없는 즉시 배포를 동시에 달성했다.
요약 이어보기채널톡 고객용 SDK에서 boot→shutdown→boot 연속 호출 시 사이드 이펙트가 중첩되는 타이밍 버그를 RxJS 기반 구조 개편으로 해결한 사례다. 비동기 흐름 직렬화에 RxJS, 동기적 상태 관리에 Zustand를 도입해 타이밍 비결정성을 구조 수준에서 제거했다.
요약 이어보기여기어때 항공 서비스 프론트엔드가 웹과 앱 웹뷰 두 환경에서 동일한 함수 호출로 동작하는 앱 브릿지 추상화 레이어를 설계한 과정을 다룬다. iOS·안드로이드 규약 차이와 "웹에 존재하지 않는 브릿지를 어떻게 호출하나"라는 문제를 단일 추상화 층으로 해결한 구현 사례다.
요약 이어보기