React.Fragment ってあんまり好きになれないなーという話
むちゃくちゃ便利な React.Fragment
ですが、個人的にはあんまり好きでないです。
おそらく自分が神経質過ぎるだけですが、それでも好きになれない理由を書いていこうと思います。
そもそも React.Fragment
とは
公式サイトを読んでもらえばわかるのであまり詳しくは書きません。
tr
とか dl
の中身をコンポーネント化したいときに使える、ちょっとトリッキーな記法です。
とはいえ dl
の直下は div
を置いても問題ないはずなので、基本的には tr
のケースでのみ使われるのかな?
React.Fragment
がなぜ好きでないのか
コンポーネントが返す DOM の最上位に記述される node が 1 つであるという保証がないため。
これによって何が起きたのか
余計なノードを書かないといけないケースが頻発している。
例
import Footer from "./Footer";
import Header from "./Header";
import Main from "./Main";
import "./style.css";
const Hoge: React.FC = () => (
<div className="hoge">
<Header />
<Main />
<Footer />
</div>
);
export default Hoge;
上記ケースでは、以下のようなスタイリングは正しく反映される保証がない。
.hoge {
display: grid;
grid-template: 160px 1fr 90px / auto;
}
なぜなら、仮に Header
が以下のようなコンポーネントだとすると、想定しているスタイリングと異なってしまう。
const Header: React.FC = () => (
<React.Fragment>
<div>fuga</div>
<div>piyo</div>
</React.Fragment>
);
export default Header;
Hoge
側からすると、Header
が返す DOM の最上位に記述される node が 1 つという保証がないため、以下のように書くのが適切ではないかと考える。
import Footer from "./Footer";
import Header from "./Header";
import Main from "./Main";
const Hoge: React.FC = () => (
<div className="hoge">
<div>
<Header />
</div>
<div>
<Main />
</div>
<div>
<Footer />
</div>
</div>
);
export default Hoge;
めんどくさくない?それ
めんどくさい、すげーめんどくさい。
世界中でこんなことを気にしているの自分だけかもしれない。
とはいえReact.Fragment
以外にも、例えばコンポーネントが null
を返すケースも存在するわけで。
コンポーネントを呼び出す側で、そのコンポーネントの戻り値の最上位に来る node が 1 つだと勝手に保証して記述を行うのは良くないと思います。
呼び出すコンポーネントをブラックボックスだと想定して、スタイリングを組むのが重要だと個人的には強く思います。
記事を書いている途中で『そういえば null
も当たり前のように返されるよね…』と思い、React.Fragment
をちょっと好きになれた今日このごろです。