-
signal에 대해서 알아보고, state와 비교 (React에서는 signal이 부적합한 이유) ⚾️웹 개발 2025. 8. 7. 23:51
React에서 Signal 기반 상태관리의 한계와 대안
요즘 상태관리에 대해서 알아보면 signal, valtio, jotai, zustand… 다양한 선택지가 있다.
그중에서도 Preact의 signal을 접하고, 리액트에 접목하는 것을 생각해봤는데, 막상 해보니 값은 바뀌는데 화면이 안 바뀐다;어째서 React에서 signal은 사용하지 못하는걸까?
Signal vs State
1. React의 useState
const [count, setCount] = useState(0);- 값을 바꾸면 (setCount) → 컴포넌트 전체가 리렌더링됨.
- 값에 접근하려면 항상 count라는 변수로 직접 가져와야 함.
- 상태는 함수형으로 관리되고, strict mode에선 두 번 실행 등 여러 규칙이 있음.
2. Preact Signal
const count = signal(0); count.value++; // 값 변경- .value로 값을 접근/수정할 수 있음.
- 값이 바뀌어도 React처럼 자동 리렌더가 안 일어남.
- 대신, 어디에서 count.value가 쓰였는지 추적해서 그 부분만 업데이트됨 (Preact에서는)
React에선 왜 signal이 안 통할까?
Preact에선 signal이 내부적으로 구독(subscribe) 기반 시스템을 돌리고 있어서, 특정 DOM만 똑똑하게 업데이트 해준다.
하지만 React는 그런 구독 시스템이 아예 없다.즉, @preact/signals-react로 signal을 써도,
const count = signal(0); // 이건 값이 바뀌어도 컴포넌트가 다시 그려지지 않음 <p>{count.value}</p>React는 signal 객체의 내부 변경 사항을 인지하지 못함.
.value가 바뀌어도 React 입장에선 아무 일도 안 일어난다.비슷한 사용방법을 가지는 라이브러리 Valtio는 왜 리렌더가 될까?
Valtio는 프록시 기반이기 때문에 React 컴포넌트가 프록시 객체를 관찰함.
const state = proxy({ count: 0 }); const snap = useSnapshot(state); return <p>{snap.count}</p>;- snap.count를 사용한 컴포넌트는 자동으로 해당 속성을 구독.
- 값이 바뀌면, 해당 부분만 리렌더됨.
- useState처럼 전역 상태도 자연스럽게 관리 가능.
작성한 테스트 코드 전체는 다음과 같다. (아쉽게도, 실제 signal처럼 컴포넌트 렌더링이 안일어나지는 않았다)
'use client'; import { useState } from 'react'; import { proxy, useSnapshot } from 'valtio'; const state = proxy({ counter: 0 }); export default function SignalExample() { const snap = useSnapshot(state); const [localState, setLocalState] = useState(0); console.log('component rendered'); return ( <div> <p>useState: {localState}</p> <button onClick={() => setLocalState(localState + 1)}>+ state</button> <p>signal: {snap.counter}</p> <button onClick={() => state.counter++}>+ signal</button> </div> ); }요약
라이브러리 사용 편의성 리랜더링 @preact/signals-react 값은 .value로 접근하기 쉬움 ❌ 리렌더 안 됨 valtio 진짜 state 쓰듯이 쓸 수 있음 ✅ 자동 리렌더 사실 Signal 개념 자체는 매력적이다.
불필요한 리렌더 줄이고, 실제 DOM을 구독 기반으로 업데이트하는 건 최적화 면에서 멋진 시도다.하지만 React에서는 아직까지 완전한 통합은 어려워 보인다.
결론 >> React에서는 아직은 state가 편하다
React의 렌더링 모델과 Signal은 본질적으로 맞지 않는다.
Preact의 Signal을 억지로 React에 끼워넣으면 값은 바뀌는데 화면이 안 바뀌는 이상한 일이 생긴다.
반면에 Valtio는 React의 라이프사이클에 딱 맞게 설계돼서 더 자연스럽게 쓸 수 있다. (내가 느끼기에는 그나마 signal과 유사하게 작동하는 상태관리 라이브러리이다)테스트를 위해 작성한 코드
https://github.com/citron03/practice-next-15/commit/7cf49c74801754cad08dee1d7695a31b22ccf2da
feat: set valtio · citron03/practice-next-15@7cf49c7
@@ -5710,6 +5710,11 @@ property-information@^7.0.0:
github.com
📚 참고자료
- Preact Signals 공식문서: https://preactjs.com/blog/introducing-signals/
- @preact/signals-react 패키지: https://github.com/preactjs/signals/tree/main/packages/react
- Valtio 공식 문서: https://valtio.pmnd.rs/
'웹 개발' 카테고리의 다른 글
GitHub Copilot과 MCP에 대한 가이드 모음 (0) 2025.09.13 package.json 패키지 버전 자동 업데이트 하기 🍕 (npm-check-updates) (0) 2025.09.06 [FE 최적화 기술] Throttle, Debounce, useDeferredValue, useTransition 쉽게 정리하기 😊 (0) 2025.07.21 리스트 가상화(Virtualization) - 성능 최적화를 위한 필수 기술 (많은 데이터 표현 시 최적화) (0) 2025.07.04 Next.js 15 App Router에서 PWA 설정하기 🍍 (0) 2025.04.11