top of page

리액트 (React)에 Signals를 사용하는 방법

미니멀 리액트 프레임워크 (minimal React framework)인 Waku의 창업자 다이시 카토 (Daishi Kato)는 지난주 리액트에서 Signals를 사용하게 하는 TC39 시그널의 실험용 리액트 훅인 use-signals를 출시하였습니다.


이 포스팅에서는 use-signals 사용 방법과 Signals가 무엇인지 간단히 알아보겠습니다.


image
Daishi Kato의 use-signals 트윗


시그널 (Signals)이란?


10년의 개발이 진행된 상태인 Signals는 클라이언트 사이드의 상태 관리용으로 Angular, Vue SolidJS, Qwik과 Preact등의 자바스크립트 프레임워크에 사용이 되고 있습니다. Signal에 변화를 주면, 값이 무효화 되면서 UI의 상태가 업데이트나 다시 렌더링이 되죠.


아래의 예제 코드는 counter라는 이름의 Signal이고 현재 0을 가지고 있습니다.



Signals는 리액트의 useState와는 본질적으로 다릅니다. useState는 함수 컴포넌트내의 상태관리와 상태 변수를 지정하고 업데이트용으로 React에서 제공하는 훅 (hook)입니다.


Signals는 비동기 이벤트나 컴포넌트의 외부에서 데이터 변경 시를 위한 이벤트 리스너 (listener)이고 옵저버 (observer)입니다. 그러므로 React와는 달리 Signal의 선언시에는 세터 (setter) 함수가 없습니다. 아래의 예제코드는 Signal이 리액트에서 선언되는 코드입니다.



Signals가 흥미로운 컨셉트인 이유는 DOM이나 UI가 애플리케이션의 상태와의 일치를 위해 리액트의 상태 값이 변할때마다 그 아래의 컴포넌트 트리가 다시 렌더링이 되고 UI가 변하는 탑다운 (top down) 모델 때문입니다.


Signal을 이용해 상태관리를 하면 어떤 파트의 UI를 다시 렌더링을 할지의 컨트롤을 좀 더 정밀하게 할 수 있습니다. Signals는 리액트의 방법보다 더 성능이 좋지만, 이 둘은 본질적으로 다르기도 합니다.


Signals의 사용법


다음의 예제와 같이 하나의 시그널 (Signal)은 constructor를 이용하여 선언이 가능합니다.



그 후에는 다음과 같이 get과 set의 메서드를 이용하여 값을 액세스하고 수정하는 작업이 가능합니다.



리액트의 Signals란?


리액트 상에서의 Signals는 위에서 설명된 바와는 좀 다르게 작동합니다. 리액트에서 자동으로 이루어지는 diffing을 스킵하는 것은 리액트의 선언적 프로그래밍의 기본 원칙을 위반하므로 리액트의 Signals는 VDOM을 그대로 사용하고 useState의 방식과 동일하게 렌더링을 합니다.


그렇다면 리액트에서 Signals가 필요한 이유가 무엇일까요? 다이시도 같은 작년에 같은 생각으로 블로그에 Why You Don't Need Signals in React라는 글을 남겼습니다.


그래서 좀 더 Signals에 대해 파고 들어가 보겠습니다.


TC39 제안


TC39 제안이 성공적이면 Signals는 자바스크립트 (JavaScript)에서는 네이티브 기능이 됩니다. 이 말은 Signals를 언제든지 사용이 가능하다는 뜻이 됩니다. 게다가 프레임워크 제작자들은 Signals를 표준화 된 방식으로 구현할 수 있게 됩니다. 현재 상황은 Signals를 사용할 수 있는 프레임워크들은 다 제각기 조금씩 다른 방식으로 구현을 하고 있습니다.


4월 11일에 Rob Eisenberg (롭 아이젠버그)는 TC39 제안이 stage 1의 단계에 돌입했다고 알렸습니다. 이 말은 TC39 제안이 ECMAScript의 검토단계에 있다는 말입니다. 아직 거쳐야 할 것들이 많지만 이 제안은 올바른 방향으로 움직이고 있는것으로 보입니다.


image
Rob Eisenberg의 TC39 트윗

TC39 제안은 Signals의 API 개발은 프레임워크에 맞추어 제작 될수 있도록 하는 것을 중요시 하고 있습니다. 그래서 위 리액트의 use-signals와 같이 Signals의 API를 사용하면서 리액트의 기본 원칙을 지키는 것이죠.


리액트의 팀이 Signals를 도입하려는 지는 다른 문제이지만, use-signals는 Signals가 React에서 사용이 될 수 있게 한 걸음 도약을 한 단계라고 볼 수 있습니다.


Signal Utils 제안


Signals는 현재 primitives만 호환이 가능합니다. 그렇지만 Object와 Array와의 호환을 위한 signal-utils 제안도 진행 중이라고 합니다.


예를 들면 아래의 예제와 같은 방법입니다:


Object:


Array:


리액트의 Signals 예제


이제는 리액트에서 use-signals를 사용하는 방법을 알아보겠습니다. 아래의 예제 코드는 Waku를 이용한 코드입니다. 참고로 Waku는 Next.js와 같이 서버사이드 렌더링이 기본이지만 use client를 이용하여 클라이언트 용으로도 사용이 가능합니다.


useState와는 달리, Signals의 선언문은 컴포넌트의 바깥에서 가능합니다. 아래의 예제는 couter라는 const를 사용하고 initial value를 지정 후에 useSignal 훅 (hook)을 이용하여 사용을 하게 됩니다.


count는 .set() 과 .get()의 메소드가 존재하고, handleInc라는 핸들러 함수 내에서 사용이 됩니다.


Signal의 값에 변화를 주면 DOM이 업데이트 되면서 UI에 보여지게 됩니다.


여기에서 특이한 점은, 리턴되는 Jsx에는 HTML <div /> 엘리먼트에서는 그 값을 액세스하기위해 .get()을 사용하지 않아도 된다는 점입니다. 대신에, count의 값은 “{count}” 같이 직접적으로 액세스가 가능합니다.



useState 컴포넌트


다른 점의 비교를 위해, 위의 내용을 useState로 사용하면 다음과 같은 코드가 됩니다.



포스팅을 접으면서


이 포스팅에서는 Signals라는 상태관리에 관하여 알아 보았습니다. 제안이 자바스크립트의 네이티브로 수락되기 까지는 시간이 걸리겠지만 useState와는 별개로 다른 상태 관리가 있고 이를 받쳐주는 커뮤니티의 활발한 활동이 있다는 것이 바람직한 현상이라고 생각됩니다.


다이시의 use-signals Github https://github.com/dai-shi/use-signals

참고:


留言


pngegg (11)_result.webp

<Raank:랑크 /> 구독 하기 : Subscribe

감사합니다! : Thanks for submitting!

bottom of page