1. kkeethのエンジニア雑談チャンネル
  2. No.117 朝活「React RFC- firs..
2022-10-24 24:47

No.117 朝活「React RFC- first class support for promise」をダラダラ読む回

はい.第117回は


use RFC
https://github.com/acdlite/rfcs/blob/first-class-promises/text/0000-first-class-support-for-promises.md


を読みました💁

相変わらず React の RFC はとてもボリューミーですね…かつ広範囲に渡って考慮した上でこれを書いているのだから,本当レベルの高さが計り知れないです😅今回もしっかり勉強させていただきます!


ではでは(=゚ω゚)ノ


  • React
  • RFC
  • use
  • react hooks
  • Layout RFC
  • React Server Components
  • Suspense
  • Motivation
  • Client Components
  • async/await
  • preload
  • Promise


See Privacy Policy at https://art19.com/privacy and California Privacy Notice at https://art19.com/privacy#do-not-sell-my-info.

00:06
10月20日、木曜日ですね。
時刻は朝9時を回りました。
今日は、いい感じの天気なんですけど、急に冬感が出ましたね。
気温が低くなったというよりも、乾燥がひどいなと思ってて、
しっかり保湿しなきゃなという感じはしますね。
はい、おはようございます。ひめみのkeethことくわはらです。
では、本日も朝活を始めていきたいと思います。
昨日ですね、うきょうさんの最速攻略、リアクトのユーズRFCというのを読んできました。
これがまとめだったんですけど、細かいところとか詳細とかを読んでみたくなったので、
本体のほうですね、RFCそのものを読んでみようかなと思っています。
貼られていたリンクはですね、もともとリアクトJSRFCsというリポジトリがあるんですけど、
それをフォークした方がいて、それに対してRFCを投げられているという感じですね。
スタートデートが10月13日というので、今月の1週間前なんてことなんですけど、
そのRFCのフルリンクが出されているという感じですね。
それについてものすごい量のコメントが出てて、スレッドすごい長いんですけど、
それら一個一個にみなさんすごい建設的なコメントがずーっと並んでて、
さすがリアクトだなという感じがしました。
では早速読んでいきたいと思いますが、おそらくですね、1日で読み終わることは多分無理だと思いますので、
明日、あさって続くかもしれないなと思っています。
たぶん3日ぐらい続く可能性が僕の中にはあるなというぐらいのドキュメント量なんで、
これのフルリンクを出したってすげーなって今思っています。
では早速いきましょうかね。
今言ったソースコードの例ですけど、これはサーバー上の非同期データにアクセスするための推奨方法です。
非同期のサーバーコンポーネンツの制限事項として、フックスにアクセスできないことがあります。
サーバーコンポーネンツはステッドレスであり、フックスはその環境ではほとんど役に立たないため、
これが問題になることはないと思われます。
しかし通常の関数として記述されたサーバーコンポーネンツの内部ではサポートされるデフックス、
例えばユーズIDみたいなのを使用することができますよということですね。
続いての例がユーズを使ったクライアントコンポーネントもしくはフックスでの例だというところで言っていますね。
ここは昨日もうきおさんの記事の通りですね。
使い方としてはユーズ括弧プロミスというのでかけておいて、それを受け取ってデータという変数に入れています。
もしくはアウェイトプロミスとしてもデータを受け取るみたいな感じですね。
アウェイトはクライアント上で動作するコンポーネント内部ではサポートされていません。
これは後のセクションで説明する技術的な制限のためです。
その代わりにリアクトはユーズという特別なフックを提供します。
リアクトはというかこのRFCが実装されればという意味ですね。
その代わりにユーズはアウェイトのリアクト専用のバージョンと考えることができます。
アウェイトが非同期関数の内部でしか使わないようにユーズはリアクトコンポーネントとフックスの内部でしか使えないようにするというのがこのRFCの特徴の一つですよと言っていますね。
03:02
他のフックスにはない特別な機能として条件やブロック、ループの中でのコールをネストすることもできます。
このためロジックを別々のコンポーネントに分割することなく条件付きで別の読み込みを待つこともできますよと。
プロミスはユーズでアンラップできる唯一の方ではないと。
コンテキストを含む追加の使える方がサポートされる予定です。
別の記事のリンクを貼られていますね。
Additional usable types will be supported というのがあるのでそこを見てくださいということでした。
一応この記事も後ほどシェアしますね。
記事というかRFCのプリリックですね。
続いてモチベーションというセクションに入るとですね。
一つ目、JavaScriptエコシステムとのシームレスな統合というところです。
私たちの主な動機の一つというのは非動機の値を表現する寛容的な方法であるプロミスがあるJavaScriptエコシステムの残りの部分とシームレスな統合を提供することです。
しかしサーバーコンポーネントの当初の提案ではプロミスベースのAPIに簡単にアクセスできるようになっていませんでした。
データソースというのは正しく実装するのが難しい特別なバインディングでラップする必要がありました。
また任意の1回限りの非動機処理をラップする簡単な方法はありませんでした。
なぜAsyncアウェイトを使わないのかというのはよく聞かれましたが、私たちは簡単に説明しましたよと。
サーバーコンポーネント、クライアントコンポーネント、シェアドコンポーネントではありますけど、
その間でデータにアクセスするために一貫したAPIを使用したいんですと。
この説明にはクライアントコンポーネントでAsyncアウェイトをサポートできないという考えが含まれています。
技術的な理由は口述しますがその通りですよと言っています。
実際、理想的にはあらゆる場所でAsyncアウェイトをサポートすることが望ましいと思います。
プロミスを私たちの独自の非動機プリミティブで置き換えたいとは思いませんし、
全ての非動機APIにリアクト固有のバインディングをラップすることを求めたいわけでもありません。
しかし最初のRFCの時点ではサーバーとクライアントコンポーネントの間で一貫したAPIを持つことがより重要なゴールであるというふうに判断しました。
これはそうですね。
その後私たちは考えを変えました。
現在ではサーバーコンポーネントにおけるAsyncアウェイトのメリットというのは、
クライアントで異なるAPIを持つことのデメリットを上回ると考えている。
なるほど。
一貫性よりもサーバーコンポーネント側の方のAsyncアウェイトを使えるようにすることのメリットの方がデカいと言っているんですね。
リアクトの思想でいくと柔軟性の方を重視するからという考えが根本的にあるような気がしましたね。
その理由の一つはサーバーコンポーネントがアドホックな非動機操作を実行する必要が生じる頻度というのを過小評価していたことです。
なるほどね。
プロミスベースのAPIというのはJavaScriptのサーバーアプリケーションではどこでもあるもので、
その全てにリアクト固有のバインディングを置かなければならないというのが完全に実現不可能ではないにしても結構迷惑な話ですよと。
これは当初の提案に対しても最も頻繁に寄せられた批判の一つだったと。
06:01
はいはいはい。
私たちはサーバーとクライアントのコンポーネント間で一貫したAPIを提供したいと思うから、
実際に他の全ての場所ではAsyncアウェイトの必要性を排除していないということに気づきましたよということでした。
サーバーコンポーネントとクライアントコンポーネントを一目で区別できるようにすることで、
開発者がどのコンポーネントをどの環境で動作しているかを常に位置決めするために精神的エネルギーを費やすなければならない不気味な谷を回避することができますよと。
難しいところですね。
一貫性があったら確かに開発者としては書きやすいし、
パッと見て過読性とか視認性とか認知の負荷を下げることができる気はしますけど、
実際の開発現場ではそれによっていろんな別の問題が発生するしなというのもあるでしょうね。
やっぱりサーバーにはサーバー固有のことを意識しなきゃいけないことがたくさんあるので、
なんだかんだサーバーとクライアントで明示的に分けるっていうのは確かに一つかもしれないですね。
あとはそもそもクライアントでできることをそんだけ増やすっていうのも本来どうなのって感じですよね。
クライアント側って本来は来たものをどう表現したりどのように見せるかっていうところが大事だったりするので、
もちろんそのデータをストアで管理してデータそのものの出し方ってのはもちろんあるんですけど、
とはいえクライアントにそんなロジックをたくさん持ってくるっていうのは僕は好きではないなという感覚があるので、
バックエンドにちゃんといろいろ集約しておいて、
その必要なものだけ最低限クライアントに抽出するのは確かにそうかなっていうのは僕は思いました。
で、非同期関数とは何かして視覚的に明確なシグナルを与えてくれます。
もしコンポーネントが非同期関数として記述されていればそれはサーバーコンポーネントですよね。
将来クライアントで非同期コンポーネントをサポートできるなとしても、
リファクタリングを容易にするために非同期コンポーネント、過去データを取得するものと、
ステートフルコンポーネントですね、いわゆるフックスを使用するものの分離を推奨し続けるでしょうと。
一般的なワークフローっていうのはデータの取得と状態の使用の両方を行う単一のコンポーネント、
状態と取得、別々に処理する複数のコンポーネントにリファクタリングすることになるでしょうと。
でも結構なんかドラスティックな感じな記述になるので、
既存のシステムとかアプリケーション、結構頑張って対応しなきゃいけない感があって、
まあまあそれはリアクトサーバーコンポーネントでも同じなんですけど、
なかなかこれが実装されているにすると、結構世界的にうわぁ頑張らなきゃっていう感じになる気はしますけどね。
では続いていきましょう。
フェッチとリーディングの間の不要な結合を回避するというところです。
フェイトとユーズの良い特性というのは、
プロミスのデータがどのように要求されたかに関係なく、
それらがどのようにフェッチされたかに関係なく、
非同期の値のアンラップのみに関係することです。
以前のサスペンションベースのデータフェッチAPIの提案では、
非同期の値を読み取るビルドインの手段がなかったため、
フェッチとレンダリングが不必要に連動してしまうことがよくありました。
データソースごとにプリロードとリードのメソッドを別々に用意して、
一方をフェッチ、もう一方をアンラップするという考え方もありましたが、
09:00
これはあくまで従来からのもので、
ライブラリー間で整合性が取れるという保証はありませんでした。
非同期の値を読み取る標準的な方法を確立することで、
フェッチとレンダリングの間の不要な結合を抑制したいと考えています。
例えばその一般的なパフォーマンスパターンというのは、
現在のレンダーをブロックすることなく、
将来のレンダーで必要になる可能性があるデータを
最適にプリフェッチすることですよというふうに言っています。
一応ソースコードで出てますけど、長いのですみません。
これは割愛します。
否定しすぎることなくリアクトに複雑性をシフトするというふうに言っています。
これまで私たちは開発者を最適でないアーキテクチャに閉じ込めたくなかったので、
データフェッチ用の公式APIというのを追加することに結構消極でした。
データ取得というのは多くのトレードオフがある大きな問題空間で、
最もうまくいく解決策は、例えばルーターなどのアプリケーションの残りの
アーキテクチャに深く統合されているものですよと言っています。
確かにリアクトはフェッチャーでの公式なものは提供していなかったですよね。
フェッチャーはたくさん世の中にありますから難しいところですよね。
標準のフェッチAPIというのもありますし、
SWCもあるし、今だと端スタックトもあるし、色々ありますからね。
しかしリアクトアーキテクチャの実装は一つではなく、
リアクトエコシステムはサードパーティーのライブラリや
フレームワークで起こるイノベーションの恩恵を受けています。
リアクトがデータ取得の仕組みについてあまりに多くの過程を立てると、
ユーザースペースに最適なソリューションが現れるのを阻害する可能性があります。
一方、リアクトがあまりに少ない過程をすると、
全ての人のために全面的な改善をする能力を失うことになります。
この提案の目標は、異なるリアクトフレームワーク間で
使用できるデータフェッチ用のプリミティブの共有セットを提供することであり、
データフェッチがフードの下でどのように動作すべきかについて
あまり否定的ではないことです。
フレームワークを切り替えても、あるいはフレームワークを使用していなくても
リアクトのコードとパターンを認識できるようにする必要があります。
例えば、Next.jsとLinuxという人気のある有力なリアクトフレームワークというのは
ルーティングやキャッシュの向こう側について異なる戦略を持っているかもしれませんが、
状態の読み込みとか条件付き読み込みとかエラー処理について
独自のAPIを開発する必要はありません。
リアクトに組み込まれているパターンを利用すればいいのです。
というか、僕はLinuxってリアクトのラッパーなのに全然知りませんでした。
確かにそうですね。リアクトのラップフレームワークとして
Next.jsとLinuxって別々の確かに機構だったりするので、
それをリアクトが本来持っていれば、それを利用すればいいだけというのは
良い思想だなと思いましたね。
関連する目標として、開発者が単純なユーズケースと複雑なユーズケースの間で
簡単に拡張できるようにすることが得られます。
アプリの要件がより複雑になるにつれて、コンポーネントをより高度な機能に
段階的にアップグレードすることができるようにする必要があります。
同様に既に高度なデータフレームワークを使用していた場合、
システム全体のアーキテクチャを損なうことなく、単一のコンポーネントに
12:02
単発なデータ取得を追加できるようにする必要があります。
データフェッチはなるべく単純単発にしたいというのはその通りだなと思いました。
モチベーションのところはこれでラストですね。
コンパイラー駆動の最適化というのを可能にしましょうと言っています。
エッシンカーウェイトというのは構文的な機能なので、
コンパイラー駆動の最適化の良い候補にはなります。
将来的には非同期サーバーコンポーネントを低レベルのジェネレーターのような形にコンパイルして
マイクロタスクのような実行時のオーバーヘッドを削減することができるでしょうが、
コンポーネントの外側の動作には影響を与えません。
また、Useというのは技術的にはJavaScriptの構文構造ではありませんが、
リアクトアプリケーションのコンテキストでは効果的に構文として機能するため、
正しい仕様を強制するためにリンターを使用しますけど、
クライアント上でも同様のコンパイラー最適化というのを使用することが可能になります。
私たちは設計全体を通じてこのことを考慮するよう配慮しました。
例えば現在のバージョンのリアクトでは、不安定なメカニズムにより任意の関数がプロミスを投げることで
レンダリング中に中断することができます。
今後のリリースではこれを排除し、利用することを優先することを予定にしています。
つまりフックスだけがサスペンドを許可されるということになります。
自動メモ化コンパイラーというのはこの知識を活用して、
任意の関数呼び出しがメモ化された計算を不必要に無効にすることを防ぐことができますよということでした。
以上がモチベーションの章でした。
続いてディテールデザインですね。
設計の詳細について入っていこうというところでした。
モチベーションを読むだけで私はお腹がいっぱいです。
リアクトの今後の方針やRFCを考えると、
エコシステムや海外のことや今後のことは大きな視点で考えなければいけないので、
エネルギーが必要だと思いました。
ただ、これを毎回やるとエンジニアのレベルとしては一気に引き上げられると感じました。
出さないにしても自分の中でこういうことを考えたり、
皆さんでワイワイやりながらこういうRFCやったらいいかもねっていうのを考える回転だけでもめちゃくちゃ勉強になりそうだなってちょっと思いました。
では行きましょう。
ディテールデザイン、詳細設計ですね。
このセクションでは非同期サーバーコンポーネンツと利用するフックの両方の技術的な詳細について以上説明していきます。
サーバーコンポーネンツはステートレスで非同期環境で実行されるため、
非同期サーバーコンポーネンツの実装というのはかなり簡単ですよと。
この提案の複雑さのほとんどはクライアントコンポーネンツ内のプロミスの読み込みに関連しており、
クライアントコンポーネンツはユーザー入力に応答して同期的にレンダリングする必要がある場合があります。
このためJavaScriptの使用で決められているプロミスの実行時動作というのを考慮すると実装するのが厄介になります。
まず非同期サーバーコンポーネンツがどのように動作するかというのを説明し、その後に使用方法を説明していきましょうというふうに言っています。
バックエンド側は確かにステートレースなので、それは簡単、シンプルであることは正しいですねって感じがしました。
じゃあいきましょう。
15:00
Asyncサーバーコンポーネンツですね。
非同期サーバーコンポーネンツからです。
ランタイムの観点からは非同期サーバーコンポーネンツとはプロミスを返すサーバーコンポーネントとして定義されています。
リアクトはプロミスが解決されるのを待ち、解決された値というのは直接返された時と同じようにレンダリングされます。
実際にはサーバーコンポーネントとクライアントコンポーネントの間のその不気味な谷を避けるために、
プロミスオブジェクトというのを直接返すのではなく、Asyncアウェイド構文を使用するようにコンポーネントを作成者に進めますよというのがまず一つ目でした。
谷を避けるためにみたいなところに別のリンクが貼られていますので、これ興味ある人はちょうど見てみてください。
一応この同じRFC内の別のリンクだというところですので、後ほど出てくると思いますけどね。
続いていきます。
非同期サーバーコンポーネントはhookを含むことができないと。
Asyncサーバーコンポーネントはcannot contain hooksですね。
注意から入っています。
非同期でない通常の関数として定義されたサーバーコンポーネントではhook様の許可されていますよというところを注意書きされていました。
その前提の上でいきましょう。
非同期サーバーコンポーネントの制約としてhookを含めることができません。
これは技術的な制約によるものですけど、サーバーコンポーネントとクライアントコンポーネントを区別するための意図的な設計上の決定でもあります。
クライアントコンポーネントを書くのに慣れているとこの制限は実は煩わしく感じるかもしれませんが、
実際にはサーバーコンポーネント、サーバー上でまたはビルド時にのみ実行されるものです。
サーバーコンポーネントで有用なhookっていうのはほとんどないので、これが問題になることはないと一応考えています。
UseStateのようなステートフルなhookっていうのは関係なく許可されていませんし、
残りのほとんど、UseMemoなどなどっていうのはサーバーとクライアントの両方の環境で実行するシェアドコンポーネントの数を増やすためにのみ使用でき、
実際には大した機能を提供していません。
ああ、はいはいはい、確かにそうですね。シェアドコンポーネントがあるんだからそっちでやればいいじゃんってなったらその通りだと思いましたね。
一般にサーバーコンポーネントのhookのほとんどの使用例っていうのは、
同じAPIのリクエストローカル版で置き換えられることが分かっています。
例えば、UseRequestHeadersのhookみたいなのがあって、
それの代わりにフレームワークっていうのはAsyncLocalStorageから読み込むGetRequestHeaders関数を提供することができます。
それはツリーごとのコンテキストである必要はないですよねって言ってます。
ただし、例外的に通常の非同期関数として定義されているサーバーコンポーネントでは、
Hooksがまだ強化されてますよと。
ああ、まあそうね、確かに。
続いて、UsePromiseですね。
今回のRCの肝であるUseですけど、そういうUseかPromiseってところでした。
Useっていうのは通常の非同期関数コンポーネントとHooksの内部で動作しながらも、
AsyncAwaitとほぼ同じプログラミングモデルを提供するように設計されています。
Javascriptの非同期関数と同様に、Useのランタイムっていうのは、
サスペンドとAzureのための内部フレームワークを維持します。
しかしコンポーネント作者の視点からは、
それはシーケンシャルな関数のように感じられますよというふうに言ってますね。
18:00
一応先ほどのソースコードの例がまた出てますね。
これは割愛します。
Javascriptの仕様によると、
Promiseの解決された値っていうのは、
常に非同期で満たされる、または拒否されるようになります。
たとえ基礎となるデータの読み込みが既に終了していたとしても、
その値を同期的に検査する方法というのはありません。
これは言語の作者による意図的な設計者の決定で、
曖昧な順序付けによって引き起こされるデータの共合を避けるためになります。
この設計の背後にある同期というのは理解はできますが、
これはある瞬間のプロップとステートの関数として
UIモデル化するリアクトおよびリアクトライクなUIライブラリに問題を提起しています。
これは言語からのサポートなしに解決するには驚くほど困難な問題です。
リアクトが使える戦略は状況に応じていくつかありますよというところですね。
それが多分いろいろ次に出てくるのかなというところですけど。
いきましょう。
中断したコンポーネントの実行を再生して再開するというところです。
Useに渡されたプロミスというのがまだ読み込まれていない場合、
Useは例外を投げてコンポーネントの実行を一時停止します。
プロミスが最終的に解決されるとリアクトはコンポーネントのレンダーというのを再開します。
この後の試行ではUseの呼び出しというのは
プロミスの履行された値というのを返します。
で、Aging Awaitはジェネレーター関数とは異なり、
中断されたコンポーネントは最後に中断したのと同じポイントから再開されません。
で、Runtimeはコンポーネントの開始と中断した場所の間にあるすべてのコードを再実行する必要がありますよ。
で、再生はリアクトコンポーネントが
アイデンポテント
すいません、僕が知らない英単語でごめんなさい。
そういうことがあると。
要求されるという特性に依存しています。
つまりレンダリング中に外部の副作用を含まず、
プロプス、ステイト、コンテキストに対して同じ出力というのを返します。
パフォーマンスの最適化として、
リアクトランタイムはこの計算の一部をメモすることができます。
これは状態の更新中にコンポーネントが再実行される方法と概念的には似ています。
概念的にはね。
で、以前に中断したコンポーネントを再開する場合、
Useの再生への依存というのはAging Awaitと比較して、
追加のランタイムオーバーヘッドが発生します。
しかしコンポーネントのデータがすでに解決されている場合、
データが事前にロードされている場合は無関係の再レンダリング中などなど、
マイクロタスク級のフラッシュを待たずに解決済みの値をアンロックできるため、
Useは実際には非同期とか待ちと比較してオーバーヘッドが少なくなっています。
意外とAging Awaitの方が有用性が高いってことかもしれないな。
こうやって書かれてみると。
続いて、再生中にプロミスの結果を読み取るってことですね。
再生中、読み取るとリーディングってところですけど。
再生中というか読み込み中な気がします。
プロミスが解決された後に中断したコンポーネントを再生する場合、
最終的にReactっていうのは前回の試行中に中断した後と同じUse呼び出しに到達します。
これは概念的には同じ呼び出しですけど、
21:00
Useに渡されるプロミスっていうのは前回の試行中に渡されたものと同じプロミスインスタンスである場合もありますし、
そうじゃない場合もあります。
しかしインスタンスが同一であるかどうかに関わらず、
その間にプロップや状態が一切変更されていない限り、
同じ結果を表すと仮定することができます。
Reactは前回の結果を再利用し、再生中に作成されたプロミスというのは無視します。
これはReactのコンポーネントがべき状の関数であることを呼び出し、
再び利用したものになりますよということですね。
続いて再生中にプロミスの結果を読み取る。
これさっき読んだやつ?
続いて、以前読まれたプロミスの結果を読む。
プロップや程度が変更された場合、Reactというのはユーズに渡されたプロミスが
前回の試行と同じ結果を持っていると仮定することができません。
それはそうだよね。別の戦略が必要になります。
Reactが最初に試みるのは、別のユーズ呼び出しまたは別のレンダリング試行によって
以前にプロミスを見取られたかどうかを確認することになります。
そうならReactは前回の結果をサスペンドすることなく、同期的に再利用することができます。
Reactはプロミスオブジェクトに追加のプロパティを追加することで、これを行いますよと言っています。
ステータスフィールドというのがあって、
こちらにはPending、Fulfilled、Rejectedのいずれかに設定される。
いわゆるプロミスの話ですね。
ステータスフィールド、他には、
さっきのPending、Fulfilled、Rejectedのいずれかに設定されて、
バリューフィールドはFulfilledの値が設定されますよと。
プロミスが拒否されると、
フィールドには拒否の理由ですね。
実際には通常エラーオブジェクトでありますけど、というのが設定されますよと。
これらのフィールドの命名というのはpromise.allSettledから釈用しています。
これはいいですね。認知的に分かりやすくて。
Reactはこれらの余分なフィールドを全てのプロミスに追加するのではなく、
使用するために渡されたプロミスオブジェクトにのみ追加することに留意してください。
グローバル環境やプロミスのプロトタイプを変更する必要はなく、
React以外の行動に影響を与えることもありません。
この規約はJavaScriptの使用の一部ではありませんが、
私たちはこれがプロミスの結果を追跡するための合理的な方法だと考えています。
理想というのは解決された値の寿命がプロミスオブジェクトの寿命に対応することであります。
これを実装する最も簡単な方法は、プロミスに直接プロパティを追加することです。
もう一つの方法はWeakMapを使うことで同様の利点を得ることです。
WeakMapの代わりにプロパティを使う利点は、
React以外のフレームワークもこれらのフィールドにアクセスすることです。
例えば、データフレームワークはReactに渡す前に、
プロミスのステータスとバリューフィールドを先取りして設定し、
Reactがマイクロタスクを持たずにそれをアンラップすることができます。
もしJavaScriptがプロミスの値を同期的に検査する標準的なAPIを採用するなら、
私たちは代わりにそちらに乗り換えるでしょう。
実際にプロミスのインスペクトのようなAPIが存在すれば、
このRFCはかなり短くなるはずです。
ただ、プロミスに手を付けるかというとそんな気はしないですけどね。
24:03
一応TC39を読んでいくともしかしたらあるかもしれないですけど、
今のところ僕がパッと見た感じはなかった気がします。
まあいいや。
というところで、時間が過ぎましたので一旦ここで区切らせていただきたいと思います。
この話はもうちょっとわちゃわちゃ続いていって終了になるからですね。
すみませんが明日も中途半端ですけど、また続きを読んでいきたいと思いますので、
興味ある人は来てみてください。
ではこちらで朝が終了したいと思います。
今日も朝からたくさんの方が参加いただき大変ありがとうございました。
また明日もゆるく読んでいきますので、頑張っていければなと思います。
では今日も一日お仕事なり、いろんなことあると思いますけど頑張っていきましょう。
お疲れ様でした。
24:47

コメント

スクロール