この記事の概要
2022年3月29日、Reactのv18.0がリリースされましたね。
公式ドキュメントの他、少し前の @uhyo さんの記事に改めて目を通していました。
上記の記事によれば大切なのは「とにかくSuspenseを理解する」だそうです。
私はデザイナーですから、スタイリング観点でいくらか考えてみました。
fallback
でよくありそうなこと(予想)
今後はこんな感じで書かれることが多くなるだろうと思っています。
const SomePage = () => {
return (
// 何かしらのコード
<div className='some-class'>
<Suspense fallback={<FallbackComponent />}>
<SomeComponent />
</Suspense>
</div>
)
}
こう書いた場合FallbackComponent
が表示されている際のスタイルが意図通りにならないかもしれません。
(問題無い場合もあると思いますが)
例えばSomeComponent
の描画が終わったとき、このようになっていて欲しいとします。
描画完了 |
---|
SomeComponent
自体はただのリストで、background-color
をつけたいのは今回がたまたま。
そのためsome-class
によってbackground-color
(付随するpadding
やborder-radius
も)を与えたという設定です。
一見良さそうですが、fallback
にも背景色がついてしまいます。
実際に表示されるfallback
|
実現したいfallback
|
---|---|
ここでパッと浮かぶのは次のようなコードでしょうか
const SomePage = () => {
return (
// 何かしらのコード
<Suspense fallback={<FallbackComponent />}>
<div className='some-class'>
<SomeComponent />
</div>
</Suspense>
)
}
SomeComponent
にだけsome-class
を与えたいのだから、当然と言えば当然ですね。
しかしこれはこれで問題です。
実際に表示されるfallback
|
実現したいfallback
|
---|---|
左の方が余白が詰まっています。(この例だと大したこと無い話ですが……。)
今回はfallback
には何もクラスが当たっておらず、かつコンポーネント自体に余白を持たせるのはバッドプラクティスのため、こういった表示になってしまいました。
ローディング中のUIで、レイアウトシフトが起きたり明らかに大きさがおかしかったりするのは割と見かけます。
デザイナー、エンジニア、どちらの守備範囲からも微妙に外れる感は分かるのですが……抜かりなく提供したいと筆者は考えています。
上記の解消方法
現状浮かんでいるのは以下の3つです。
- レイアウト用ユーティリティクラスを作っておく
- レイアウト用コンポーネントを作っておく
-
fallback
用コンポーネントはclassName
などを受け取れるようにしておく
1と2はイメージしやすいと思います。
const SomePage = () => {
return (
// 何かしらのコード
<Suspense fallback={<div className='mt-1'><FallbackComponent /></div>}>
<div className='some-class'>
<SomeComponent />
</div>
</Suspense>
)
}
const SomePage = () => {
return (
// 何かしらのコード
<Suspense fallback={<Margin top={1}><FallbackComponent /><Margin>}>
<div className='some-class'>
<SomeComponent />
</div>
</Suspense>
)
}
だいたい上記のようになると思います。
議論が起きそうなのは3でしょうか。
「コンポーネントの責務を逸脱するので受け取れない方が良い」という意見はあるはずです。
筆者は個人開発だったらclassName
を渡せるようにしちゃうケースが多いのですが、チームでとなると微妙ですね。
いずれにせよ「fallback用コンポーネント
をそのままfallback
に渡すとスタイル崩れが起きるかもしれない」と認識してスタイル設計に臨むのが良いのかなと思っています。
最後まで読んでくださってありがとうございます!
Twitterでも情報を発信しているので、良かったらフォローお願いします!