音声書き起こし
1. オープニング
@spring_raining
こんにちは、UITの玉田です。今回もUIT INSIDEを始めたいと思います。
UIT INSIDEはユーザーインターフェースとテクノロジーを愛する開発者のためのPodcastです。
最新のWeb標準の動向や開発フレームワークの変遷、UIやUXに関することまで、毎週フロントエンドの情報を発信していくことを目的としています。
@spring_raining
はい、 今回はですね、えっと、前々回ですかね、鴻巣さんに出ていたと思うんですけど、そこでちょっと出た。
React 18へのアップグレードの件について、えっと、今回はもう少し
@spring_raining
詳しく聞いてみたいという、趣旨でお呼びしました。それでは、鴻巣さんよろしくお願いします
@kazushikonosu
はい、よろしくお願いします
2. LINEバイトとReact
@spring_raining
え、今回はですね、鴻巣さんに来ていただいたんですけれども。エピソード127でVite 3の話をしたと思うんですけれども。
そこで、React 18にアップグレードしたという気になる情報を聞きまして、そこについてどうですかね、LINEバイト のプロジェクトですよね、
@kazushikonosu
はい、そうです、
@spring_raining
はい、そうですそこの話とかも含めて聞いていきたいです。
じゃあ、そうですね、ま、いきなりですけど、LINEバイトのまあ、普段の開発の様子とかを教えてもらえますか。
@kazushikonosu
はい、えっと、まず、LINEバイトがどんなサービスか知らない方もいると思うので、説明しますと、LINEバイトは、LINEのバイトサービスそのままなんですけども、 特徴としては、LINEのサービスとしては、あのLINEのアプリの中 からだけじゃなくて、通常のブラウザーでも、アクセスすることを想定して、できてるウェブアプリになってます。技術スタックは、割とベーシックな感じで
@kazushikonosu
TypeScriptとReactとReduxを使って、まあ、Styled-componentsとかを使ってる感じです。ただ、特徴的だなって思うのが SSRを行っていてと、そのためにNext.jsじゃなくて、自前でサーバーサイドレンダリングのロジックを書いてたりします。
@spring_raining
おーはい、そうですね、その自前サーバーサイドレンダリング気になりますので、あとで聞いてみますね。
はい、そうですね、で、えっと、まあ、普段そういうReactのまあ、技術スタックのプロジェクトになっているんですね。じゃあ、React 18にあげようと思ったきっかけというか、
誰が発起人だったりとかするんですかね。
@kazushikonosu
あ、そうですね、なんか、元々結構バイトのあのチームの中では結構技術的な関心が高くて、いろんなライブラリとかについては、興味があるんですけど、 React 18については、僕が個人的な興味であげたいっていうところがすごい強くてま。それ以外にも結構。
えっと、useEffectとかを使ってこう状態管理してるのが
@kazushikonosu
に限界を感じていて、そこをsuspenseとかでどうやって解決できるんだろうっていうところの興味もあった感じです。
@spring_raining
ああ、なるほどなるほど、まあ、やっぱりsuspenseを使いたい、使うとだいぶ楽になりそうだ という予想だったんですね。
@kazushikonosu
そうですね、結構うん。Reduxでプレーンにこう書いてる
@kazushikonosu
状態、管理が辛い部分が多かったので、suspenseで解決できるなら、したいなっていう動きはありました。
@spring_raining
うん、うん、うん、なるほど、ありがとうございます。じゃあ、具体的などういうことをやったかっていうのは教えてもらいますか。
@kazushikonosu
そうですね、なんか、React 18にアップグレードするにあたって、また、準備のところで、他のそのライブラリだったりとか、どういうところを影響が出るんだろうみたいなところが、 そこに結構時間をかけていて、あの、実際調べたところ、react-routerだったりとかで、こうバージョンアップが必要だっていうところがあったので、 えっと、まその作業とかから始めた感じですかね。
@spring_raining
はあ、はいはい、React本体のまあ、アップグレードもそうですけど。そうですね、大体そういう あのフレームワークのアップグレートって、周辺のライブラリとかのアップグレードとかとセットですよね。
@kazushikonosu
そうですね、結構react-router以外にもreact-helmetだったりとか。
えっと、SSRの手法が変わることによって、ライブラリのアップグレードが必要になるところが多くて、そこのリサーチを中心に作業が必要だった感じです。
@spring_raining
なるほど、そうですね、これのアップグレードをやったというところですけれども、そうですね、まあ、変更点、実際に行動を書き換えたところでいうと、どなたですかね。その、ライブラリのアップグレードももちろんあると思うんですけど、 コードの変更でいうと、ほんとにReactの公式のガイダンスにしたかった感じですね。
@kazushikonosu
あ、基本的には割とコードのガイダンスと、あとはあのissueが立てられてて、SSRとかの場合だったりとか、そこのissueとかを読みながら で、Reactのアップグレード自体ができたんですけど、も。えっと、suspenseを使うために、そのSSRが今までrenderToStringみたいなを使ったのを、 ストリーミングAPIに対応させる必要があって、そこの部分でSSRのロジックをまるっと書き換える必要があったのが、結構作業としては大きかったなと思います。
@spring_raining
ふんふんふんそうですね、それはあのまあNext.jsとかではなくて、もうあの、自前のサーバーサイトのプログラムが元からあって、それを対応ですね。
@kazushikonosu
そうです、はい、
@spring_raining
結構大変そう
@kazushikonosu
そうですね、やっぱり、あの、Next.jsとかを使ってるのと違って、レガシーになってるようなコードも残ってたりするので、実際、この部分はどういう風に挙動してるんだっけ。みたいなところとかを確認しながら、 こう。デグレが発生しないように、コードを書き換える必要があったので、そこらへんはReactのアップグレード以外で結構大変だったかなと思います。
@spring_raining
ああ、そうですね、デグレとか、ちなみにあのQAとか、リグリッションテストとかは、どういう感じに進められましたか。
@kazushikonosu
LINEバイトは結構、QRAの体制が充実していて、普段からリリース前にはリクレッションテストを行ってるんですけど、それとは別にフルリグレッションテストみたいなのを定期的にま、数ヶ月に1回ぐらいの頻度で行っていただくことがあって、そうですね。具体的な人数で言うと、QAさんが5人いてま、その人たちが、えっと、4、5日ぐらいかけて、一通り全部の機能を
@kazushikonosu
チェックしていただくみたいなことができて、そういう機会を使って、ライブラリのアップグレードとか。今までもできてた感じです。
@spring_raining
あ、なるほど、まあでもそういうバックアップがあるっていうのは心強いですね。結構
@kazushikonosu
でも、ほんとにQAさんのおかげで、チャレンジのこともできてるなって思って。
@spring_raining
いや、いいですね。そのリグレッションテストがあったとして、その変更点、サーバサイトレンダリングの変更点自体の作業はどんな感じですかね。ほんとにAPIの書き換えだけで済んだ
@kazushikonosu
あ、結構多分バイトの例だと、Styled-componentsを使ってるのが大きくて。で、基本的にStyled-componentsのドキュメントっていうのが、そのSSRでrenderToStringを使うことを想定していて、あまりReact 18のの新しいストリーミングAPIを想定していない感じなんですね。
@spring_raining
うん、はい、
@kazushikonosu
ま。ただ一応そのReact 17以前のストリーミングAPIのためにちょこっとドキュメントが乗っていて、 それと、React 18のストリーミングAPIの仕様が若干違うんですけども、そこを工夫すれば、あの、基本的にはそこまで大きな変更は必要なかったかなと思います。
@spring_raining
あ、なるほど、そうですよね、まあ周辺のライブラリの対応次第ではあるものの、意外とそこまで何週間も困ったみたいな感じでもない
@kazushikonosu
そうですね。なんか、Reactのアップグレード自体は他のその機能実装とかもしながらなので、こう正確な数字はわからないですけど、1週間もかからなくて。
その下準備のところのパッケージの他のパッケージのアップグレードですね特に、react-routerのアップグレードがすごい辛くて、それにすごい時間を取られた印象です。
@spring_raining
そうですね、はいはいはいはい、そうですよね。ちなみに、バージョン5からバージョン6へのアップグレードという風に聞いてるんですけど。
@kazushikonosu
あ、そうですね、
@spring_raining
うん、結構変更点が大きい、
@kazushikonosu
結構破壊的な変更がすごい大きくて、ま、ただこれv5だと、あのReact 18のsuspenseとかがうまく動かないみたいな話がissueとかで上がってたりしたので、これは避けて通れないってこと。なるほど、ま、この機会にせっかくだから、やるかっていうことになりました。
@spring_raining
ああ、それは仕方ないですね
@spring_raining
何かをアップグレードするために、他のアップグレード作業が必要になるってのがかなりしんどい。
@spring_raining
そうなんか、本題に入れないもどかしさがありますね。
@kazushikonosu
ま、ただ、なんか、react-routerのアップグレードについては、そのreact-router v6はReact 17でも動くので、
@spring_raining
なるほど、
@kazushikonosu
そのバージョンを分けて、あ、react-routerのアップグレードと、Reactのアップグレードのバージョンを分けて、 別々でQAして、こう。デグレを防ぐことができたので、そういう工夫次第ではこうなんとかまあなんとかなるかなっていう感じです。
@spring_raining
そうですね、あ、それはいいですね。ま、でも逆に言うと、例えばReact 19とかが出てきたら、そういう手が取れないっていう のがあるので、まあ、上げるタイミングとしては、かなり良かったかもしれない。
@kazushikonosu
そうかもしれないですね、結果的には
@spring_raining
うん、ありがとうございます。じゃあ、まあアップグレードした感想とかは、 後ほどゆっくり聞かせてもらいたいなと思います。
3. React 18での変更点
@spring_raining
今までは 実際にアップグレードした背景みたいなのについて。えっと聞いてきましたが、ちょっと。まあ、私もそもそもその
@spring_raining
業務開発で、React最近は触ってないっていうところもあり、復習をした方が良いかなと思いました。で、React 18ま そもそも、どういったところが変更されたかっていうところをえっと、見ていこうと思います。で、はいはい、えっと、そうですね、一応UIT INSIDEでもReact 18 alphaが登場し、たとえー登場した時にエピソードとりまして、エピソード89なんで
@spring_raining
ま、結構前にとりました。はい、で、まあそこからなんかsuspenseとかなんか色々話したんですけれども、まそれについて はい、えっと、振り返りたいと思います。で、そうですね、suspenseを使いたいってのが、今回のモチベーション だったかなと思うんですけども
@kazushikonosu
そうですね。
@spring_raining
うん、うん。
@kazushikonosu
suspenseを使いたいってのが、1番のモチベーションだったと思います。
@spring_raining
はい、あとあのまこれ。あの、実際私もほんとに読んだだけぐらいの知識でしかないんですけど。サーバーサイドレンダリングのストリーミング っていうのもと、えっと、suspenseは関連しているっていうところで、これもあの結構 有効活用してますかね。React 18にあげてから
@kazushikonosu
そうですね。suspenseを使うためには、ストリーミングが絶対条件だったので、ストリーミングに対応したっていうところで、 実際にストリーミングにしたことによって、SSRの初期ロードが早くなったとか、メトリックとかは今のところはれてないですね。
@spring_raining
ああ、なるほど、はいまあ、あの、ほんとにアップデートしたてと思うので、それは多分これからですよね。
@kazushikonosu
あ、そうですね、これから、ストリミンーグAPIとsuspenseの組み合わせで、SSRの最適化とかもできたらいいなっていう風には思ってます。
@spring_raining
そうですね、ありがとうございますで、えっと、一応もう1つあのtransitionとか が。えっと、React 18でも使えるようになるんですけれども、これを今後導入していく予定は
@kazushikonosu
そうですね。結構バイトだと、フォームとかがあったりして、あ、結構複雑なフォームとかがあったりし。
@spring_raining
ああ、はいはい、
@kazushikonosu
そういうところでこうレンダーがすごいいっぱい発生するみたいなのはあったりするので。
まだ試してないですけど、React 18のこう1つメリットだと思うので、そこも試せていけたらなという風に思ってます。
@spring_raining
あ、なるほど、じゃあそういったまあそうですね、フォームとか結構あの頻繁に更新があって、数が多いと結構もそうですね。
@kazushikonosu
そうですね、こう入力するたびにこうrenderがかかっちゃったりすると、 そこでユーザー体験が悪くなっちゃうので、こういうstartTransitionとかで、抑制できるなら、すごい試したいなっていう風に思います。
@spring_raining
うん、ありがとうございます。そうですね、ここほんとに、あの、私がその業務のReactとを知らないっていうのは、どこかのタイミングでやりたいなっていう気持ちはあるんですけど、なんか結構なんてすかね。
すごいなんとなくって、すごい言い方悪いですけど、なんとなくReact使って
@spring_raining
ま。一応、そのコンポーネントとか、スタイルの当て方とか、そういったところは分かりつつも、まあ、suspenseはなんとかわかるが、transitionまで行けてないみたいな、そういう感じなんで、実際に使ってみて、ほんとに早くなるのであれば、試したい。
@kazushikonosu
そうですね。
@spring_raining
うん、あの、これこれは完全に私の技量の問題なんで、 ああ、そうですね。えっと、確かエピソード89で出たと 記憶があるんですけど、Strict modeで、そのuseEffectの、挙動が変わるみたいな。そういった話とかもありましたね、あれはどうですかね、なんかやってみたりしました?
@kazushikonosu
そうです。Strict modeは、最初有効にするかどうか 迷ってたんですけども、結局、そのプロダクション環境では、Strict mode入れても入れなくても、特に挙動が変わらないので、 とりあえず有効にしていいかみたいな話になりました。で、実際Strict modeにしたことで、なんかローディングが2回走ったりとか。
@spring_raining
あーはい
@kazushikonosu
コンポーネントが二重で表示されたり。みたいなのは発生してるんですけど、ま、開発環境だけでしか発生しないので、こう手を入れるタイミングで、ちょっとずつ直せていけたらいいな、みたいな、そういう方針になりました。
@spring_raining
あ、じゃあまそれはそうですよね、何も考えてなかったら絶対そうなりますよ。
@kazushikonosu
そうですね、ま、ただ結構React 17以前から、多分、eslintのルールで、hooksのdependencyのルールみたいのがあると思うんですけど。あれでこう全部指定してないとエラーが出るみたいな
@spring_raining
ああ、なるほど、
@kazushikonosu
ちゃんと守って開発してると ま、結構最近書いたコードについては、そんなに変な挙動は起きなかったです。むしろ、多分、hooksとかを理解してない状況で書いてた古のコードで、問題が発生していたみたいな印象があるので、そんなに大きな問題は起きないのかな、という風に思います。
@spring_raining
ああ、いや、でもそれはあれです。そのコードのメンテナンスをちゃんとしている、という証ですよ。
@kazushikonosu
いや、でも、eslintのルールのおかげで、結構そのちゃんとしたhookの書き方の思想に合ってるhookの書き方みたいなのを、こう今までできてたのかなっていう風に思います。
@spring_raining
はい、そうですよね、あの、私もあの、なんて言うんですか。そのdependencyに入ってる なんか、重複してるものとか、入ってないものとか、そういったレベルではチェックしてるんですけど、確か多分空の配列だとエラーになるみたいなのは、 まだ何もしてなかったかも。いや、でも、そうですよね、雑に書いてたら、後で苦しんでしまうという
@kazushikonosu
そうですね空の配列とか、本当に本当に空の配列じゃないと実現できない時だけにしてこう。空の配列じゃなくて、ちゃんとそのdependencyを指定しても、動くように 行動直せるなら、直してみたりとか、そういうことをこう普段からやってれば大丈夫なのかなって気がします。
@spring_raining
なるほど、普段の行いが
4. React 18にアップグレードした感想
@spring_raining
あのアップグレード無事に終わったということで、まあ、実際どういうところが良かったかなとか、どういったところで、 まあ苦労してます。とか、さっきのStrict modeのまあ件とかもそうですけれども、こうどういった感想を抱きました。
@kazushikonosu
そうですね、なんか、すごい良かったところとしては、やっぱ最初のモチベーションの あのeffectを使った状態管理のところでも、ちらっと話したと思うんですけども。
suspenseを使うことで、ローディングの状態をコンポーネントの外に出すことができるので、カスタムフックを書いた時に、
@kazushikonosu
ま、例えば、あるデータをフェッチするにしても、今までであれば、データ、もしくはundefinedみたいな、そういう方の返り値のhookが できると思うんですけど、それがデータだけみたいになって、
@spring_raining
ああ、はい、
@kazushikonosu
その後の条件分岐とかがすごいクリアになって、そのローディングとかの部分で、本質とは関係ない条件分岐ですごいこう。今まで考えさせられてたんだなっていうのは思ったんで、そこを直せてすごいよかったなっていう風に思ってます。うん、
@spring_raining
うん、ああ、やっぱりそうなんですね。確かに見た目で減るっていうのはそうなんですけど、それ以上に結構そういう本質じゃない ところが紛れてるっていうのは、それほどほんとによかった点だった。
@kazushikonosu
そうそうですよね、結構多分、コードサンプルとかだと、1つのコンポーネントに1つのデータソースみたいなのが多いと思うんですけど、実際の例、そのプロダクションのコードって、 あるデータに依存して、別のデータがあったりとか、こう1つのコンポーネントに複数の
@kazushikonosu
fetchしなきゃいけないデータとかがあったりとかして、そうすると、この増えれば増えるほど、このデータはローディングしてるっていうのを、こう考えることが増えるので、それを全部こうpromiseを投げることで、コンポーネントの外にこう追いやることができて、すごい見通しがよく、ああ、なるなという風に思います。
@spring_raining
そうなんですよね、いや、すごくわかります。その複数のAPIがあって、まどの順番にfetchするかとか、そういったのがどんどん複雑になっていくんですね。
@kazushikonosu
うん、そうですね、あと、型がすごい簡単になるので、
@spring_raining
あ、はいはいはい、
@kazushikonosu
そうその辺でもこうあ、ここは本当はundefinedでは来ることはないけど、型的にはundefinedが来るから、なんかエラーを投げなきゃとか、そういう
@spring_raining
うん、うん、
@kazushikonosu
そういう本筋から離れたところからの問題が全部なくなるので。ああ、この辺はすごい体験がいいなと。
@spring_raining
はいはい、なんか型上ではundefinedだけど、実際にはundefinedになることはないみたいな。
@kazushikonosu
そうですね、undefinedになることはないから、ここではundefinedで出ることはありません。みたいなエラーを投げたりとか、そういうことはしなくていい。
@spring_raining
ああ、なるほど、それはいいな。 あと、ちなみに、ちらっとあのReduxの話が出てきたかなと思うんですけれども、基本的にそういうsuspenseを使うっていうのは、新しく書いたコードなんですかね。それ。それとも、あの、既存のそのRedux噛ませたコンポーネントをsuspenseに置き換えるっていう作業を進めている感じですかね。
@kazushikonosu
ここは、ちょっとまだ方針が定まってないんですけども、一旦試したものはと、Reduxで、 えっと、サーバーからフェッチした情報を保存してるものを、suspenseで書き換えたっていう感じですね。ただ、ちょっとあんまりReduxとsuspenseの枠組みが相性がよくなさそうなので、そこはどうしようかなっていうのをちょっと悩んでるような状況です。
@spring_raining
そうですね、あんまり私もRedux時代のを思い出すと、あんまりあの組み合わせが良くないな、というのは 想像できますね。
@kazushikonosu
そうですね、なんか例えばですけど、なんか結構バイトのコードだとあるAPIのリクエストを投げるときに、一旦ReduxでisFetching、 このローディングの状態を表現するストアの状態を更新して、フェッチが完了したら、またそれを戻すみたいなことをやってるんですけども、 それをsuspenseでやっちゃうと、そのsuspenseでフェッチするようなthunkを投げると、その瞬間に
@kazushikonosu
状態が更新されて、そうすると、Reduxがリレンダーを発火して、またsuspenseが投げられて、の無限ループが発生しちゃったりとかして、 多分suspenseだと、ローディングとかは、全部Redux側に任せるみたいな思想だと思うんですけど、なんか、Reduxはそのローディングとかも、 この開発者が考えなきゃいけないみたいなところなので、そこでこううまく合わないなっていうのは思います。結構そのために、suspenseで投げたプロミス
@kazushikonosu
を一時的に保存するようなhookを作ったりだとか、その間は同じthunkが投げられたとしても、実際の 状態の書き換えを行わないようにするみたいなことをやったり、そのトリッキーがコードが出てくるので、Reduxをsuspenseを組み合わせる ていうのは、あんまりいいアイデアじゃないんだろうなっていうところだな気がしてます。
@spring_raining
までもそこは既存プロジェクトなので、まあ、なかなかこう、コストとリターンでいうコストのところっていう
@kazushikonosu
ま。なので、suspenseにアップグレードして、その利点をマックスに使いたいなら、Reduxで サーバーの状態保存するのはやめて、react-queryだったりとか、別のソリューションにした方がいいのかなっていうところなんですけども。またそれも マイグレーションに時間かかるし、難しいなっていう感じがしてます。
@spring_raining
あの、アップグレードと違って、全然考え方が違うんで、だいぶ難易度上がりますよね。うん、
@kazushikonosu
そうですね、なんで、なんかあのま、特にそのAPIの情報とかの話で言うと、多分suspenseだと、別にそのサーバーで から取得したデータは、リレンダーを発火するようなステートである必要はなくて、でも、Reduxって 情報を書き換えると、リレンダーが発火するじゃないですか。そこら辺もあんまり相性が良くなくて、やっぱりもう最終的に解決するには、react-queryとか
@kazushikonosu
Reduxで管理するのやめなきゃいけないんだろうなっていう気はします。
@spring_raining
なるほど、じゃあ、次はReact 18アップグレードの次はRedux、脱Redux
@kazushikonosu
かもしれない。
@spring_raining
じゃあ、そうですね、あの、最後になんかこれさっきのReduxの件も そうなんですけれども、なんか既存のもし、Reactプロジェクトがもしあった場合、どういったケースでこうアップグレードした方がいいとか、まあ、どういった人がどういったプロジェクトで、アップグレードするのが良いのかっていうアドバイス的なのがあると聞きたいんです。
@kazushikonosu
そうですね、やっぱりLINEバイトでも、その最初にモチベーションとしてあった状態管理 がすごい複雑でこうuseEffectとかだと、手に負えないみたいな部分は、suspenseだったりを使うことによってすごい解決できると思うので、特に大規模な プロジェクトであれば、あるほどReact 18に移行して、あの、そういう部分を見直す価値はあるのかな、という風に思います。
@kazushikonosu
ただ、一方で結構そのsuspenseとかでこう。今までのReduxのメンタルモデルからは、ちょっと違う考え方を完全に変えなきゃいけないので、そこの学習コストみたいなのは多分すごい大きいなと思っていて、 そういう部分が難しいようであれば、ちょっとReact 18にアップグレードするのは、考える必要があるのかなっていう気もしてます。
@spring_raining
ありがとうございますなるほど、いや、すごいあれですね、こう 大規模であればあるほどリターンは多いけれども、それだけ大変というなかなか難儀な話ですね。まあ、ほんとにこう。
LINEバイトはかなりフルリグレッションとかが出厚いという話はあるんですけど、それでも
@spring_raining
まあでもほんとにアップグレードしたことによって、今後こう受け続ける。こういう負債とかが今返せたっていうところは、ほんとに そこも考えてアップデートしたいですよね。
@kazushikonosu
そうです で、実際suspenseとか使わなくても、とりあえずReact 18にアップグレードして、React 17以前と同じように使うみたいなこともできるので、 ま、全然。とりあえず、アップグレードするっていうのも、選択肢としてありだなっていう風に思いました。
@spring_raining
ありがとうございますああ、はいはいはい、ほんとにこれをあの聞いている皆さんに ま、もしかしたら結構もうでもReact 18割と前ですよね。もう結構半年ぐらい
@kazushikonosu
そうですね。
@kazushikonosu
なんだかんだ時間が経ってしまって、
@spring_raining
こういったのは、こう後になれば。なるほど、どんどん大変になっていくものなので。
@kazushikonosu
いや、ほんとそうなので、早めにやることをおすすめします。
@spring_raining
これを聞いたタイミングで、もし検討してもらえると、多分 将来幸せになるんじゃないでしょうか。じゃあ、はい、ありがとうございます。
5. クロージング
@spring_raining
はい、今回はえーReact 18にアップグレードした話について、え、鴻巣さんに聞いていきました。
LINEのフロントの組織UITでは、このような技術的なキャッチアップを日々を行っております。
UIT INSIDE以外にも、毎週の社内勉強会で、フロントエンドの情報交換を行っています。
@spring_raining
今後も、UIT INSIDEをと通して、このような情報を外部に発信していけたらと思います。
最後に、現在LINE株式会社では、新卒、中途採用とに大募集しています。
このポットキャストを聞いて、LINEに興味ををもたれましたら、Shownote1番下にある求人ページから、ぜひアクセスしてください。
@spring_raining
それでは、鴻巣さんありがとうございました、
@kazushikonosu
ありがとうございました。