00:07
はい、6月11日土曜日。朝はちょっと9時9分ですね。ちょっと回ってしまいました。
本日はですね、まさかの外、ここは代々木公園ですね、の芝生で今やってます。
おはようございます。ゆめみのキース孤独は原です。では本日もまた活動を始めていきたいと思います。
はい、えーと今回はですね、タイトルのある通り、引き続きSolid.jsの入門のドキュメントを読んでいこうかなと思ってます。
はい、アプテラの堂さんですね。ありがとうございます。ご参加いただきありがとうございます。
ちょっと今回は朝、外でやってますので、もしかしたら、いろんな雑音が入ってしまっているかもしれないです。申し訳ないです。
はい、ラスコさんですね。ご参加ありがとうございます。
じゃあ今日から、えーとSolid.js前回はですね、コンポーネントAPIとストアのところまでやったので、今日から副次的なプリミティブと
いけたらレンダリングまでちょっといきたいかなと思っています。
はい、まあ公式ドキュメントをダラダラと読んでいく感じなので、ラジオ的に聞いていただければという感じですね。
はい、じゃあ行きます。一つ目ですね、副次的なプリミティブ。おそらく初めてのアプリには必要ないでしょうが、あると便利なツールですよということでした。
まあユーティリティと似てる感じだと思いますけど、より内部的な関数ばっかりになるのかなと思いますね。
はい、えーと今回のプリミティブの関数は5個ありますね。
クリエイトなんたら系の関数ばかりです。
まあ1個1個読んでいきましょう。
一つ目、クリエイトDefferedって感じです。関数ですね。
はい、これ何かというと、ブラウザーがアイドル状態の時にダウンストリームの変更のみを通知する読み取り専用の変数を作成しますと。
はい、で、引数の中にTimeoutMSっていうのがありますね。
このTimeoutMSっていうのは、強制的に更新を行うまでの最大待機時間、あーなるほどですね、っていうのを持ってくれるというものだそうです。
ブラウザーがアイドル状態の時に使うものだそうですね。
基本的には読み取り専用の変数っていうのを作ってくれるらしいです。
はい、で続いて、クリエイトコンピューティットですね。
こちらの関数は、依存関係を自動的に追跡してレンダリングの直前に実行する新しい計算を作成します。
これは他のリアクティブプログラム、プリミティブに書き込むために使用します。
更新の途中でシグナルに書き込むと、他の計算で再計算が必要になることがあるので、可能であれば代わりにクリエイトメモを使用してくださいという感じですね。
Vue.jsでいうとこのコンピューティットに近いのかなとニュアンス的に思いました。
ただ自動的に追跡するとかなので、一旦普通にステードとかデータの管理してはクリエイトシグナルを使って、いわゆる状態管理すればいいと思いますけど、
それも多分依存関係なので、より関係性深いところまで追跡したいという時にこれを使うのかなとなんていうのかと思いましたね。
03:05
その書いてある通りですね、Reactive Primitiveに書き込むために使うというので、厳密に言うとデータ管理というものではないと思うので、ちょっと用途は違うんですけどね。
で、キャッシュしたければクリエイトメモそのまま使ってくださいよということでしたが、今回のプリミティブの話はサンプルコードが全然ないのでちょっと分かりづらいかもしれないですね。
では続いて、Create Render Effectという感じですね。
はい、こちらは依存関係を自動的に追跡する新しい計算を作成し、計算を作成し、まあまたエフェクトですもんね。
マウント後に実行されるのかな、これ。
ドム要素が作成及び更新されるが必ずしも結合されていないレンダリングフェーズで実行します。
すべての内部ドムの更新はこの時点で行われます。
ああ、はいはいはい、なるほどですね。
ドムの更新はこの時点で行われるというので、ここにフックかけてわちゃわちゃと別の計算処理とかを挟みたいときに使うのかなという感じですね。
もちろんCreate Effectというのがもともとベースのプリミティブがあるんですけど、それとまた別のものかなと思いますね。
まあただ基本的に今見た感じはCreate Effectで十分ほとたれる気はしますけど、それのもう少し細かな配慮とか制御したいときに使うのかなって思いましたね。
続いてCreate Reactionですね。
こちらはちなみにバージョン1.3以降に使えるものだそうですね。
こちらは追跡と再実行を分離することが便利な場合があります。
まあそれはそうですよね。
認知はしたいけど何もしないときもあるし、分けたいときあると思います。
このプリミティブっていうのは返された追跡関数によってラップされた式が初めて変更を通知されたときに実行される副作用を登録しますと。
難しいな、日本語も長いしちょっと難しいですね。
ソースコードのサンプルがあるのでちょっと見ていきますと、Create Signalで適当に文字列をイニシャルバリでセットしますと。
で、レスポンスにセッターとゲッターの関数が受け取られますよね。配列で受け取ります。
1つのコンスとトラックイコールで関数を定義しておいて、ここにCreate Reactionですね。今やったやつを定義しますと。
この中の引数にコールバック関数をセットしていて、これは単純にコンソールログで何かをしますよっていうものですね。
っていうようなトラックっていう関数を1個定義しますと。
このトラックを実行するときですね、このトラック自体が関数なので実行するんですけど、そのとき実行される引数ですね。
引数もまたコールバック関数で何かしらのSっていう関数を使います。
今回のサンプルコードではCreate Signalのゲッター関数ですね。
06:02
っていうのをトラックで実行して呼んでみましょうと。
そのときにセッター関数を呼ぶと、なるほど。
1回目は何かやってくれるってことで、2回目以降は更新時のみ反応するため何もしないってことを検知できるってことですね。
あくまで変更検知をしてくれるっていうことだそうですね。
なのでCreate Reactionでいわゆるサブスクライブですね。
オブザーバブルのサブスクライブ的なものをセットしておいて、
そのトラックっていうのを実行したときに中身の方で変更検知とかをずっと監視していて、
変更があったときのみ何かを実行するっていうのを外部的にフックかけることができるって感じですね。
ちょっと口頭で難しいと思いますので、この辺はソースコードを見ていただくのが分かりやすいかなと思いますが、
そういう使い方ができるので、結構面白いなと思いましたね。
新たなフック関数的に変更検知を仕込むっていうことができるので、
これはこれで面白いなと思いましたし、これがデフォルトで組み込んであるっていうのは
僕らが独自実装しなくていいっていうのは結構嬉しいなと思いました。
続いてプリミティブがラストですね。
Create Selectorっていう関数です。
こちらは値と一致するキーが入った、または出たときにのみサブスクライバーに通知する条件付けシグナルっていうのを作成します。
基本的には状態管理をするものですね。
委任された選択状態とかの場合には便利ですよと。
ちなみに演算がOの括弧NではなくてOの2になるそうですね。
Oっていうのはいわゆる計算数の話ですね。
ちょっと読み方忘れましたけど。
ONではなくてOの2になるので結構計算が少ないよってことだそうです。
使い方としてはReactのHooksと同じような感じでCreate Selectorっていう関数で
Selected IDとかを例えば引きずにセットしてあげます。
レスポンスは単純にBoolean値がレスポンスに返ってきます。
なので今回のサンプルコードとIsSelectedっていうのを変数に受け取ります。
IsSelectedの値に対して何か処理をしてくださいねっていうことだそうですね。
これは説明にあった通りですけど
サブスクライバーに通知する情報を作成するので
ここは結構自動的に検知とか状態変化っていうのも
ここも見てくれそうな気はしますね。
ただレスポンスで返すのがあくまでBoolean値なので
ちょっと使いどころはニッチな状態になる気がしますね。
サンプルコードのこのSelected IDっていうのはどういうIDなのか
ちょっとよく分かってないので
もう少し使いどころが難しいというか
イメージがちょっと僕はしづらかったですね。
09:03
一回書いてみると分かるかもしれないし
公式が結構サンプルアプリを作ってるので
その辺のソースコードで出てきたものをちょっと見たいなと思いました。
というところで副次的なプリミティブこんな5つありましたね。
一応知らなくてもいいけどあると便利だよっていうような使いどころなので
本当にニッチなケースで使うときにこの辺を参照すると良さそうですね。
では副次的なプリミティブは今ので以上で
続いてレンダリングの章に入っていきたいと思いますね。
レンダリングも特に関数がいっぱい書いてあるんですけど
こちらはそもそもソリッドJSのスラッシュウェブっていうライブラリーですね
NPMに公開してるらしいんでそこから
インポートしてくれればいいですよっていうふうには書いてますね。
そのインポートの中のいくつかの機能があるので
それをちょっと勉強していきましょうかね。
合計が1,2,3,4,5,6,7個ありますね。
1つ目はレンダリングなのでまずレンダーという関数です。
これはブラウザアプリのエントリーポイントですね。
トップレベルのコンポーネントで定義または関数として
マウントする要素を指定しますよと。
返されたディスポーズ関数というのがあって
その関数が全ての子供を消去するので
このエレメントっていうのを空にすることをお勧めしておきます。
使い方としてはリアクトのレンダーと同じような感じですね。
第1引数にコンポーネントのオブジェクトを足しておいて
第2引数にどこのHTML要素にマウントするのかっていうのを指定してますね。
今回のサンプルコードではドキュメントエレメントバイIDのアップみたいな感じになってますね。
レスポンスにディスポーズというのがあって
このディスポーズ関数を使えば全ての子供を消去できるらしいです。
こういうのを持たなければそのままレンダーして終わりになりそうですね。
以上レンダー関数でした。
続いてハイドレート関数ですね。
これも多分似たような機能だと思いますけど
ちょっと読んでいきますね。
こちらはレンダーと似ていますけども
すでにDOMにレンダリングされているものを再利用しようとする点が異なります。
すでにレンダリングしたものを使うんですね。
ブラウザの初期化時にはページはすでにサーバーでレンダリングされています。
なるほどですね。
単純にブラウザだけじゃなくてサーバー側との処理の話も入ってくるんですね。
これも使い方は一緒ですね。
ハイドレートっていう関数をレンダーと同じようにコールします。
第一引数にはレンダリングしたいコンポーネント。
第二引数にどこのHTMLにマウントするのかっていうのを指定します。
ソースコードも全く一緒ですね。
getElementByIDのアップでマウントして処理をしてますね。
レスポンスもやっぱりdisposeっていうのを受け取って
それを初期化できるって感じです。
子供を消すことができるって感じですね。
レンダーと本当に見た目上は全く似てますけど
性質としては既にあるものっていうのも再現をしてる点が異なるよってこと。
12:03
そこだけですね。
タイプスクリプトの型定義も書いてあるんですけど
こちらも一緒ですね。
1個目が関数で2個目がエレメントっていうのがそれにつきます。
ギミックセット関数っていうかJSXエレメントですね。
っていうのが第一引数でした。
では続いてrenderToStringっていう関数ですね。
こちらは文字列に同期的にレンダリングをしますと。
この関数っていうのはプログレッシブハイドレーション用の
スプリクトタグも生成してくれますと言ってますね。
なのでレスポンスはstringとは書いてますけど
htmlの文字列ですねこれは。
オプションにはページがロードされて
ハイドレーションの再生前に行読するイベントネームと
スクリプトタグにつける難数ですねっていうのがあります。
難数ってのはちょっとよくわかってないですけど。
っていうオプションがありますよと。
レンダーIDっていうのが考慮されていて
こちらが複数のトップレベルルートがある場合には
レンダリングの名前空間を作成されるために使用されますと
っていうのが内部的にレンダーIDっていうのがあるらしいですね。
このrenderToStringっていう関数の定義を今見ているんですけど
第一引数はコンポーネントですね。JSXエレメントで
第二引数にオプションズっていうのが
名前通りオプショナルで指定することができるんですけど
そのオプションズがオブジェクトになっていて
その中にさっきの難数とレンダーIDっていうのが2つあります。
っていうのでこれを使うことも一応できはしますよってことですね。
先ほど言った通りですけど
トップレベルルートが複数ある場合
そんなアプリケーションを作るか別として
作った場合は名前空間を作りたいがために
このレンダーIDっていうのを使うと良いでしょうと言ってます。
使い方は今までと一緒ですね。
renderToStringっていう関数で
引数にマウントしたいコンポーネントのインスタンスか
コンポーネントというかJSXエレメントを渡してあげて
レスポンスには単純に文字列が返ってきますね。
HTMLの文字列が返ってくるよという感じでした。
一応でも先ほど説明にあった通り
プログレッシブハイドレーション用のスクリプトタグも生成してくれますので
それも組み込んだHTMLが返されるってところですね。
ハイドレーションしたいって時にもこれが使えそうな気がしました。
続いてrenderToStringAsyncっていう関数ですね。
先ほどの非同期処理が追加になっているような感じの名前ですね。
ちょっと読んでいきますと
結果を返す前に全てのサスペンス境界が解決するのを待つという点を除いて
renderToStringと全く同じです。
非同期処理としてはサスペンスのものが組み込まれているということですね。
リソースデータは自動的にスクリプトタグにシリアライズされて
15:00
クライアントのロード時にはハイドレーションされますよと言ってますね。
こちらも同じように第一引数は
カラスがうるさいですね。
第一引数はJSXエレメントがあって
第二引数はオプショナルでオブジェクトがあります。
オプショナルの中にはtimeout.msとrender.idとnanceという3つが定義できますよと言ってますね。
このrender.idの使い方はさっきのrenderToStringと全く一緒ですよって感じです。
ただtimeout.msもさっき出てきたものと一緒そうですね。
どれだけ時間待ちますかっていうのを指定できる感じです。
ただこれを数字で指定すればいいって感じですね。
文字通りasyncなのでその秒数とかを指定できるという風に今のところ見えますね。
こちらはですね、全く一緒って言ったんですけど
renderToStringはレスポンスがストリングなんですけど
renderToStringAsyncは名前通りAsyncなのでレスポンスはpromiseが変わりますね。
promiseの文字列っていう感じのものが変えると思います。
ここだけちょっとやっぱり違いますね。
なので使い方としてはrenderToStringAsyncを使うときは
awaitを前につけてやることが良さそうですね。
サンプルコードもそういう感じになってます。
続いてrenderToStreamっていう関数ですね。
今度はストリームのレンダリング関数ですね。
こちらはですね、もちろんストリームにレンダリングするメソッドなんですけど
サスペンスのフォールバックプレイスホルダーを含むコンテンツを
同期的にレンダリングして完了すると任意の非同期リソースから
データとエキテンエイルをストリームし続けますよという風に言ってますね。
使い方としてはノードとWebストリームで
ソースコードちょっとサンプルコード分けられていて
ノードの方はrenderToStreamっていう関数実行で
引数にはJSXエレメントですね。
もしくはコンポーネントのオブジェクトをそのままセットします。
ドットパイプっていう関数があって
パイプの中にレスっていう変数を引数に渡してますけど
全くコンテキストがないのでこの関数見てもちょっとよくわかんないですね。
パイプで何か繋げれる処理ができるんだなってことは分かりましたが。
Webストリームの方はコンストで値を受け取りますと。
今回は名前でそのまま受け取っていて
redoubleとwritableっていう2つのものがあるらしいですね。
で、イコールニュートランスフォームストリームっていうので
インスタンスを作ってますね。
そのredoubleとwritableを使って
renderToStreamのアップでまたドットパイプ2で
さっきのやつを引数に渡してあげると。
自分で読んどいてこれ何やってるか全然わかんないので
流してください。
サンプルコードがあまりにもコンテキストがなさすぎる。
一応この関数の中の引数に渡すものとして
18:02
オプショナルに色々あるんですけど
今回の関数のオプショナルには
onCompleteShellというものと
onCompleteAllという2つのオプショナルのものがあって
これは関数ですね。
これの説明がちょっと書いてあるので
読むだけ読んでいこうと思います。
onCompleteShellというのは
同期レンダリング完了してから
最初のフラッシュをストリームに書き出して
ブラウザに出力するときに発生されます。
onCompleteAllというのは
全てのサーバーのサスペンス境界が
確定したときに呼び出されます。
レンダーIDは同じようなものです。
同期レンダリングが完了してから
最初のフラッシュをストリームに書き出し
ブラウザに出力するときに発生する。
もちろんレンダリングが完了のところに
フックをかけて何かを押せるというふうには見えますけど
もちろんレンダー関数なので
その辺の話ですよね。
同期レンダリングと言っているので
さっきのAsyncとはまたちょっと違う話ですね。
完全にちゃんと同期が終わるところですね。
あとはNode.jsとの関わりの話を
もうちょっとしているので
そこともレンダリングするのかな?
というふうに見た感じは思いますね。
Complete Allというのは
さっき言った通りですけど
サーバーとのサスペンス強化が
全部確定したときに呼び出される。
サスペンスが全て解決したら
何かをするときに使う感じですね。
それをストリームとして流すという通りですね。
このSolid.jsは僕まだ全然書いていないので
このSolidのドキュメントで出てくるストリームというのが
一般的なストリームの話なのか
ここの中にちょっと特殊なものがあるのか
というのは全然僕はまだ理解できていないので
分かっている方は
あ、そうなんだって聞いていただければいいですけど
僕は全然分かっていないです。
一応このAPIというのは
以前のpipe-to-writableと
pipe-to-node-writable APIというものが
もともとあったらしいですね。
Solid.js。
これの置き換えになることを
注意してくださいということでした。
昔からSolid.jsを書いている人にとっては
これなるほどってなるかもしれないです。
続いてレンダリングの次の関数で
isServerというものがありますね。
こちらは単純にBoolean値を返すものですね。
すみません、これ関数じゃなくて
単純に変数でした。
これ内部的に最初から組み込まれている変数だそうです。
で、Boolean値が返ります。
これはコードがサーバーまたはブラウザのバンドラルとして
実行されているかどうかというのを示してくれます。
できそうとなるランタイムが
この値を定数のBool値としてエクスポートするので
バンドラーというのはコードと
その使用されるインポートを
それぞれのバンドラルから取り除くことができますよ。
使い方は単純にBoolean値なので
if文でisServerというのを見て
trueであればブラウザバンドラルには入りませんよと。
elseだったらサーバーで実行されませんよという感じですね。
というところです。
とにかくisServerというところで
21:01
このコードがサーバーなのか
ブラウザバンドラルかというところを
検知できますよという感じでした。
これは結構分かりやすくかつ
使いどころがありそうだなと思いましたね。
最後レンダー関数は
ハイドレーションスクリプトというものですね。
この子だっけ?
頭は大文字ですね。
パスカルケースですね。
使いどころは
これちゃんと関数だな。
ハイドレーションスクリプトというのは
ソリッドのランタイムがロードされる前に
ハイドレーションを起動するために
ページ上に一度配置される特別なスクリプトになります。
HTML文字列に挿入して呼び出す関数として
またはHTMLタグからJSXをレンダリングする場合は
コンポーネントとして提供もされますよと言ってますね。
確かに片手に見てると
レスポンスはJSX.ELEMENTですね。
この関数の引数として
またオプショナルのものがあるんですけど
オプションはスクリプトタグに付けられるNANSと
スクリプトがロードされる前に
ソリッドが取得して
ハイドレーション中に再生されるイベント名の
2つが渡すことができますと言ってますね。
これらのイベントっていうのは
ソリッドが異常するものに限定して
合成やバブルってなんだ
バブルなどのUIイベントが
そういうことバブリングの話ですね。
UIイベントが含まれるよと
デフォルトではクリックおよび
インプットイベントのみになっていると。
結構限定したものなんですね。
イベントっていうのは。
正直なところ言うとこちらも
読むだけだと全然わからない感じですね。
なるほど。
この辺レンダリング関数なんで
あんま最初意識しなくて良さそうなところですね。
レンダリング前後で
色々細かく制御したいときに
使うという感じだと思います。
ランタイムがロードされる前に
っていう風に書いてるんで
そこの辺にフックをかけたい人は
この関数を使うといいんだろうなと思いました。
使いどころによってはちゃんと普通に
JSXとかコンポーネントとして提供されるので
最初は意識しなくても良さそうには見えますね。
ちょっとニッチな使い方になる気はしました。
あとはスクリプトに付けられる
取得するイベント名っていうのが
今のところクリックとインプットイベントしか
まだ渡されるとか設定できなさそうですね。
デフォルトではって書いてあるんで
新しいのもフックかけられるんでしょうけど
ちょっと怪しそうだなと僕は全く感じました。
この辺をやるような複雑なアプリケーションの
ときに使うんだろうなと思いますけど
あんまレンダリングのイベントとかを検知して
フックかけてわちゃわちゃってやるのは
ちょっと僕の中で気なくさいので
必要があればもちろんやるんですけど
一旦保留として頭に片隅に残すだけに
しておこうかなと思いました。
24:02
以上レンダリング関数7項ですね。
一つはただの変数ですけど。
っていうのがレンダリングでした。
残り今日はちょっと
あと7分か9分か忘れましたけど
ちょっとオーバーしたので
もうちょっと続けようと思います。
区切りとして
次の章入ると区切りが中途半端なので
1,2個ぐらい入って終わろうかなと思いますね。
次のセクションは制御フローっていうところですね。
制御フローっていうのは
いわゆるコンポーネントの話だと思いますけども
ちょっと読んでいきますね。
リアクティブな制御フローが
パフォーマンスを発揮するためには
要素がどのように作成されるかを
制御する必要があります。
例えばリストの場合は
単純なマップっていう関数
これはJavaScriptのマップ関数ですね。
単純なマップっていうのは
常に配列全体をマップしてしまうので
やっぱり効率的ではないよね
って話をしてました。
これはヘルパー関数を意味しています。
これらをコンポーネントで
ラップすることによって
簡潔なテンプレートを作成するのが便利ですし
ユーザーが独自の制御フローを
構成構築することもできます。
これらの組み込み制御コンポーネントってのは
自動的にインポートされます。
ポータルとダイナミック以外の全ては
Solid.jsからエクスポートされますよ。
DOMに特化したこれらの2つっていうのは
Solid.jsスラッシュウェブから
エクスポートもできます。
ただし、制御フローのコールバックもしくは
レンダー関数のことも全て追跡されませんので
これによって状態をネストして作成でき
反応をより良く分離できますよ
というところは注意でした。
というので、ここから
制御フローの
Solid.js独自のコンポーネントが
ここからバーッと流れていく感じになりますけど
区切り的にちょうどいいので
ここで区切ってしまおうかなと思いました。
また明日、改めてこの制御フローの説明
注釈を読んでから
中に入っていこうかなと思いますので
今日は一旦こちらで以上にしたいと思います。
今日も今日で
なかなか分かりづらかったり
不運みたいなお話ばっかりで
大変に申し訳ないなと思いますけど
まだ引き続きお付き合いいただけたら
嬉しいなと思いますので
今日はこちらで以上にしたいと思います。
土曜日ですね。
朝からですけどご参加いただいた皆さん
大変にありがとうございました。
良い休日をお過ごしください。