반응형 프록시 상태의 구상
제5화
발행일: 2025년 05월 28일
다이시 카토의 손가락은 더 이상 망설이지 않았다. 그의 머릿속에서 흩어져 있던 아이디어의 파편들이 자바스크립트 Proxy라는 강력한 자석에 이끌려 하나의 명확한 형태로 응축되기 시작했다. 키보드 위에서 춤추듯 움직이는 손가락은 그의 구상을 코드로 옮겨낼 준비를 하고 있었다.
"핵심은… 극도의 단순함이야."
그는 중얼거렸다. 개발자가 상태 관리를 위해 배워야 할 것은 최소한이어야 했다. 아니, 거의 없어야 했다. 마치 마법처럼, 자연스럽게 작동해야 했다.
그의 머릿속에 첫 번째 퍼즐 조각이 맞춰졌다. 바로 상태 객체를 '마법 거울'로 변환시키는 주문, proxy()
함수였다.
import { proxy } from 'valtio'; // 미래의 모습
const initialState = {
count: 0,
user: { name: 'Guest', age: null },
items: [],
};
const state = proxy(initialState); // 이 한 줄로 마법은 시작된다!
"개발자는 그저 평범한 자바스크립트 객체를 넘겨주기만 하면 된다. 그러면... 마법이 시작되는 거지."
proxy()
함수는 내부적으로 전달받은 initialState
객체를 new Proxy()
로 감싼다. 그리고 이 프록시 객체(state
)야말로 개발자가 앞으로 상호작용할 대상이었다.
이제 개발자는 이 state
객체를 가지고 무엇이든 할 수 있었다. 마치 냉장고에서 재료를 꺼내 요리하듯, 필요한 상태를 자유롭게 꺼내 쓰고, 변경할 수 있는 것이다.
// 카운터 증가시키기
state.count++;
// 사용자 이름 변경하기
state.user.name = '다이시 카토';
// 배열에 아이템 추가하기
state.items.push({ id: 1, text: 'Valtio는 직관적이다!' });
// 중첩된 객체의 속성 변경하기
state.user.age = 30; // 가상의 나이
// 속성 삭제하기
delete state.user.unusedProperty;
"이거야…! 이게 바로 내가 원했던 모습이야!"
카토는 탄성을 내질렀다. 특별한 set
함수도, produce
콜백도 필요 없었다. 그저 자바스크립트의 기본 문법, 할당(=
)과 증감 연산자(++
), 배열 메서드(push
), delete
연산자를 사용했을 뿐이다. 하지만 Proxy의 마법 덕분에 이 모든 '평범한' 작업들이 특별한 의미를 갖게 된다.
Proxy 핸들러의 set
트랩은 state.count++
나 state.user.name = '...'
같은 할당 연산을 가로챈다. deleteProperty
트랩은 delete state.user.unusedProperty
를 감지한다. 심지어 push
같은 배열 메서드 호출로 인한 내부적인 변경까지도 Proxy는 놓치지 않고 잡아낼 수 있었다. 물론 배열 메서드 처리는 좀 더 정교한 핸들링이 필요하겠지만, 핵심 원리는 같았다.
이 트랩들은 단순히 변경을 감지하는 것에서 그치지 않는다. 변경이 발생하면, 즉시 내부적인 알림 시스템을 작동시킨다. "이봐! 상태가 바뀌었어!" 라고 외치는 것이다. 그리고 이 알림이야말로 상태 변화에 '반응'하여 UI를 업데이트하거나 다른 로직을 실행하는 열쇠가 될 터였다.
"단순히 객체를 감싸는 것을 넘어… 이건 '반응형 프록시 상태(Reactive Proxy State)'라고 불러야 해."
카토는 자신의 아이디어에 이름을 붙였다. Proxy를 통해 객체의 변경을 투명하게 감지하고, 그 변화에 '반응'하여 연쇄적인 업데이트를 일으키는 시스템. 이것이 바로 그가 구현하고자 하는 새로운 상태 관리 패러다임의 핵심이었다.
마법 거울은 더 이상 단순한 반영이 아니었다. 그것은 모든 변화를 놓치지 않고 기록하는 감시자이자, 변화가 일어났음을 알리는 전령이었다. 개발자는 거울 앞에서 자유롭게 춤을 추기만 하면 되었다. 거울이 알아서 모든 것을 처리해 줄 테니까.
Zustand의 set(state => ({...}))
나 Jotai의 setCount(c => c + 1)
과 비교했을 때, 이 방식은 압도적으로 간결하고 직관적이었다. 개발자의 인지적 부담을 혁신적으로 줄여줄 잠재력이 보였다.
물론 아직 넘어야 할 산은 많았다. React와의 통합 문제, 성능 최적화, 중첩 객체 및 배열 처리의 세부 구현 등. 하지만 가장 중요한 첫걸음, 핵심 아이디어의 구체화는 성공적으로 이루어졌다. 다이시 카토의 눈빛은 확신으로 빛나고 있었고, 그의 손가락은 이 혁신적인 아이디어를 현실로 만들 코드를 써 내려갈 준비를 마쳤다. 세 번째 왕국의 설계도가 그의 머릿속에서 완성되고 있었다.