React.Fragment ってあんまり好きになれないなーという話

2020-06-14

むちゃくちゃ便利な 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 をちょっと好きになれた今日このごろです。

React.Fragment ってあんまり好きになれないなーという話 - kk-web