1
/
5

useSignal ~SolidJSやqwik等で話題のSignalsについて深掘りしてみる~


さて、今回はタイトルにもある通り、Signalsについて詳しく見ていこうと思います。

Signalsといえば、新進気鋭フレームワークであるSolidJSやqwikで採用されている技術ですが、1ヶ月ほど前にこのSignalsの話題でフロント界隈が少しざわついていたように見えたので、気になって色々と調べてみました。

今回はそこで知ったことをまとめた記事になっています。

そもそもSignalsとは何なのか

Signalsは状態を保持するための手段です。

基本的にはReactにおけるStateと同じような概念になります。

ただしこの二つにはしっかりと違いがあつので、この記事ではその違いを見ながらSignalsの特徴を抑えていきます。

useStateとの違い

useStateとuseSignalの返す値を見てみる

それぞれ簡単なカウンターアプリを例に違いを見ていきます。

まずはuseStateを使ったReactのコードです。

import { useState } from "react";
export const Counter: React.FC = () => {
  const [count, setCount] = useState(0);
  return (
    <button onClick={() => setCount(count + 1)}>
      {count}
    </button>
  );
};

countというstateの値とsetCountというcountを更新するための関数が返っていますね。


続いてSolidJSにおけるSignalsを見ていきます。
※SolidJSでSignalsを扱う場合は、createSignalというAPIを使います。

import { Component, createSignal } from "solid-js"'
export const Counter: Component = () => {
  const [count, setCount] = createSignal(0)
  return (
      <button onClick={() => setCount(count() + 1)}>
          {count()}
      </button>
  );
};

useStateと違い、countが関数になっているのが分かります。

ここでは、useStateが返すのはvalueとsetterであり、createSignalが返すのはgetterとsetterであることがわかります。
言い換えると、useStateは値の実体を返しており、useSignalは値への参照を返しています。これが重要です。


せっかくなので、同じくSignalsを扱うフレームワークのqwikの例も見てみましょう。

import { component$, useSignal } from "@builder.io/qwik";
export const Counter = component$(() => {
  const count = useSignal(0);
  return (
    <button onClick$={() => count.value++}>
      {count.value}
    </button>
  );
});

qwikの場合は、countが「value」というプロパティを持ったオブジェクトになっているのと、countを更新するときはそのcount.valueをそのまま操作しているのがわかります。

使い方の違いはありますが、このvalueプロパティはSolidJSにおけるgetter/setterの立ち位置となっており、こちらも値の実体ではなく値への参照を返しています。


レンダリングの挙動を見てみる

各フレームワーク/ライブラリ毎に、カウンターボタンを押してsetterを実行した時のレンダリングの挙動を見てみます。

それぞれコンポーネントのレンダリング時にログで「rendered」と出力するようにしています。

まずはReactのuseStateから。


3回ボタンを押して見ました。

ログを見てみると、3回「rendered」と出力されています(ボタンを押す直前にログを一度クリアしています)。

ボタンを押し、setterで値が更新されるたびにコンポーネントがレンダリングされています。


続いてSignals。

まずはSolidJSから見てみます。

3回押してみましたが「rendered」と出力されないので、コンポーネントは再レンダリングされていないようです。

qwikもSolidJSと同じ結果でした。

結果的に、Stateは更新時にコンポーネント全体を再レンダリングするのに対し、Signalsは更新してもコンポーネント自体は再レンダリングされず、Signalsの値を表示しているテキストのnodeだけが更新されています。


なぜこんな挙動に?

一言でまとめると、「useStateによって返される値は非リアクティブ、useSignalによって返される値への参照はリアクティブであるから」といえます。

リアクティブであるということは、値が更新されたことを検知して、その値を呼び出しているところにその更新を知らせる必要があります。Signals(値への参照)は、どこでそれが呼び出されたかを監視し、呼び出されている箇所に値の更新を知らせてくれるという、subscriptionの動きをします。
よってSignalsはコンポーネント全体を再レンダリングする必要がなく、呼び出された部分だけを更新するだけでいいということになります。

このように、Signalsは最初からレンダリング回数が抑えられているため、再レンダリングのコストについて頭を抱えることも少なくなるんですね(逆に再レンダリングして欲しいのにしてくれないみたいな悩みもあるようです)。

いろんなフレームワークで採用されているSignals

このSignals(リアクティブな状態管理)はいくつかのフレームワークで採用されています。

先程SolidJSとqwikを例に出しましたが、最近PreactやAngularでもSignalsを採用する動きがありました(他にもあるかも)。

また、Vue.jsのshallowRefというAPIも「Signals」という名前は使っていないものの、かなり似た設計になっているようです。
よくよく考えると、shallowRefに限らず、よく使われるrefも挙動的にはSignalsっぽさがありますよね。

筆者の意見を少し

あくまでも主観ですが、JSフレームワーク界隈(?)全体的にSignalsを採用する流れがある印象です。
ただ、Reactは依然として変わらないあたり、なんとなくMetaらしさを感じます。

この記事の内容的に、かなりSignalsを推しているように思われるかもしれませんが、
そもそも再レンダリングのコストはそこまで気にすべきでないといった主張があることからも、
useState、useSignalを比較する上で、どちらが優れているといった議論はあまり意味を成さないのではないかと思います。

さいごに

ここいらで少し宣伝を…

4月もロジカルスタジオで勉強会が開催されます!!!

日時:2023/04/14(金) 19:00 ~ 21:00

場所:株式会社ロジカルスタジオ

テーマ:WEBフロントエンドのお話 TypeScript etc…

詳細:https://coroutine.connpass.com/event/279026/

金曜の夜、さくっと勉強して帰りませんか…?

たくさんのご参加お待ちしております!!


また、ロジカルスタジオでは積極的に採用活動を行っています。
少しでも興味を持っていただけた方は、下記よりご応募ください!お待ちしております。

フロントエンドエンジニア
チームと共にプロジェクトを成功へ導くテクニカルディレクターを募集!!
ロジカルスタジオは、テクノロジーとデザインの視点からクライアントの課題解決をめざす、大阪のクリエイティブプロダクションです。 クライアントの期待を超えて「もっと良くなる、を見つける」のが私たちのスタイル。企画・提案からデザイン制作・システム構築、運用、改善提案をワンストップで行えるのが一番の強みです。近年ではその実績と品質が評価され、案件も急増しています。 代表の古川が掲げる企業理念は「絆を大切に、周りの人を豊かにし、社会に貢献する」。 私たちはこのミッションを推進するため、「新しい技術へのチャレンジ精神」を軸に、「切磋琢磨する仲間」と「働きやすい職場環境」を整え、「成長と可能性を大切にする風土」を育ててきました。 2019年9月に増床し、外部向けのセミナーにも活用できるカンファレンスルームを拡充。スタッフによる公式ブログや、マスコットキャラクター「ロージー&カール」によるTwitterなど、情報発信も強化しています。 可能性の芽をすくい上げられるこの場所を、より大きくしていきたい。 私たちと一緒に、このビジョンを実現しませんか。
株式会社ロジカルスタジオ
Invitation from 株式会社ロジカルスタジオ
If this story triggered your interest, have a chat with the team?
株式会社ロジカルスタジオ's job postings
4 Likes
4 Likes

Weekly ranking

Show other rankings
Like 岩村 充基's Story
Let 岩村 充基's company know you're interested in their content