🍃このブログは移転しました。
3秒後、自動的に移動します・・・。

Solid.jsを試してみた感想

実際の案件で、3ヶ月くらいかけてコードを書いてみての感想。

TL;DRとしては、

  • 思ってた通りに良いものではある
  • が、手放しで褒めるにはあと一息
  • 今後に期待したい

という感じ。

Better React(!Next.js) alternatives

という視点で、よかった点をいくつか。

JSXはやはり楽ちん

やっぱりJSXの取り回しの楽さはよい。っても比較対象はSvelteくらいしかないけど。

  • Propsでもコンポーネントを自在に渡せる
  • LocalProps & JSX.ButtonHTMLAtrributes<HTMLButtonElement>できる

このあたりはSvelteの明確な弱点であり、少しずつ改善はされてても現時点ではまだまだなので、そういう意味で。

軽い

もとよりSignalsに根ざしてるというところで、CSRメインな場合に、React+αのαの選定に悩まずSolid一本で全部済むのは体験としてもよい。

そしてバンドルサイズも軽い。V-DOMなんかいらんかったんや。

コンポーネントのDX

const Counter = () => {
  const [count, setCount] = createSignal(0);
  const doubled = createMemo(() => count() * 2);

  return (
    <button onClick={() => setCount((c) => c + 1)}>{doubled()}</button>
  );
};

というコンポーネントがあったときに、

  • returnされてない部分は、一度だけ実行される
  • returnされた部分は、その後もアップデートされる

という「リアクティブな値がトラッキングされる仕組みとそのスコープ」についての理解は必須。

ここがReact経験者からすると慣れが必要なところではあるが、React未経験な人からしたら、どっちが自然に感じるのかは気になるところであり、良し悪しというか、そういうもんって割り切りをするだけかなーと。

コンポーネントのPropsをDestrucuturingしてはいけないという縛りも、長くやってるとむしろ安心するようになってる自分がいた。

return (
  <div>
    Before: {props.name}
    After: {draftName}
  </div>
);

こういう例みたく、どの値がProps経由で外界から渡されたもの?ってのがひと目でわかるから。

オプショナルなPropsに初期値を入れたい場合だけ、mergeProps()っていうユーティリティを使う必要があって、そこは確かにちょっとだけ手間。

自動レンダリング最適化

lealog.hateblo.jp

この記事でも少し触れてるけど、ForShowという特別なコンポーネントを使うことで、いわゆるメモ化を任意のブロック単位でできるのがすごく良い。

もちろん三項演算子{items.map()}みたいな書き方もできるので、適材適所で使ったらいいのかなと。 (配列の中身が配列ごとアップデートされるような場合は、全入れ替えになるのでForコンポーネントで書いても意味ない)

使い分けを悩むこと自体が問題だというなら、徹底して使う側に倒すといい。MobXのときのobserver(Comp)と同じ。

気になるところ

APIがEasyすぎる

これは完全にIMOではあるが、APIセットはもっとシンプルでいいなと感じる。

まずcreateResource()というSWRライクな書き方で非同期処理を抽象化できるAPIがあるけど、キャッシュの機能がないので、いわゆるAPIにつなぐ使い方ではあまり実用的でない。 コンポーネントを非同期に読むlazy()の裏側で使われてるとはいえ、どのみち@tanstack/solid-query使うわ〜となるなら、最初からその存在を意識したくないなって。

https://www.solidjs.com/docs/latest/api#createresource

あとTree-shakeされるとはいえ、RxJSとつなぐためのAPIがコアに入ってるのも、なんか節操ない印象を受けてしまう。

もひとつ個人的に言うと、サブパッケージになってるとはいえ、createStore()は魔術みがすぎる。

https://www.solidjs.com/docs/latest/api#createstore

甘い香りに誘われて最初は使ってたけど、あとで見直したときに嫌な予感がしたので使うのをやめた。

コンパイラがBabelベース

別に動いてるからええやんって話ではあるけど、なんかちょっと気になってしまう。なんとなく、先行きは大丈夫なんだろうか?って。

https://github.com/solidjs/solid/tree/main/packages/babel-preset-solid

そしてそのBabelプラグインを支えるdom-expressionsっていうライブラリが、またまたRyan氏の個人リポジトリにあったり。

いや、別にいいけど、なんだかちょっとだけ不安な気持ちというか・・・。

ちなみにSWCのプラグインとしてこのあたりを再実装してる人もいるけど、それが本体に取り込まれるかは不明。(たぶん起こらない気がする)

https://github.com/modderme123/swc-plugin-jsx-dom-expressions

というような、ふとしたときに感じる属人性が気になるという話でした。

エコシステム

Reactのそれにはもちろん遠く及ばんとしても、なんでもかんでも外部のライブラリに頼りたいわけじゃなければ、なんとかなるかと。

CSRメインのプロジェクトで採用する分には、

このあたりがあれば事足りるし、あとはVanillaなライブラリをよしなに組み込めばいい。

SolidStartは個人的に路線があまり好きではないのであんまり追ってないけど、そんなに活発に開発されてる印象はなくて、この先どうなるんやろうなーって感じ。

おわりに

Solid 2.0に期待してるぞ・・・!

The ideal Solid? (v2, v3, v4, etc) · solidjs/solid · Discussion #1804 · GitHub