【React】関数と関数コンポーネントのメリット・デメリット

例えば、以下のように書いて

function Component() {
  return <h1>Hello</h1>;
}

コンポーネントを利用したい場所で<Component>と書いてコンポーネントとして使う方法がありますが

 

それとは別に、以下のように書いて

function component() {
  return <h1>Hello</h1>;
}

この関数を呼び出したい場所で{component()}と書いて「JavaScriptの関数を埋め込んで、その関数からJSXを返す」みたいな方法もあります。

関数コンポーネント

どちらも同じ結果になりますが、結論から言うと基本的には前者を使うべきです。

 

なぜなら、

  • 前者の特徴:
    • <Component>だと「なんらかのJSXを返すんだろうな」というのが確定している
    • <Component>うんこ</Component>みたいに書けば、うんこという文字列をComponentprops.childrenとして渡せたりもするし、他にも<MyContext.Provider>などの便利機能がいろいろ使える
    • 場合によっては再レンダリングを抑えることができる。例えば「<Component>の中身が変わらないのであれば再レンダリングしない」みたいなことができる。
  • 後者の特徴:
    • component()が何をするのか予測しづらい。
    • もしかするとJSXを返さないかもしれない。

という理由。

 

基本的に、{}を使ってJavaScript文を埋め込む場合は

{flg 
  ?<h1>Hello!!</h1>
  :<h1>Good Bye!!</h1>
}

のように「条件式を使うために仕方なく使う」みたいなケースでしか使用しないほうが吉。

関数

逆に、JSXを返さずに

  • 単に数値を返すだけ
  • 単に文字列を返すだけ

みたいな場合は後者でいいと思われます。

 

あと「単にコードを見やすくしたい」というだけが目的の場合、わざわざコンポーネントに分けてしまうと、いちいちpropsを渡さないといけなかったりするので、その場合も後者の方が良いと思われます。

例えば以下のようなコンポーネントがあったとして

function Company(props) {
  return (
    <>
      <h1>会社概要</h1>
      <p>props.gaiyou</p>
      <h1>会社役員</h1>
      <p>props.yakuinn</p>
      <h1>事業内容</h1>
      <p>props.zigyounaiyou</p>
    </>
  );
}
  • 会社概要
  • 会社役員
  • 事業内容

の3つをそれぞれ分離したいとします。(この場合は分ける意味はまったくありませんが。。)

 

これを後者の方法で分離する場合、以下のように書けます。

function Company(props) {
  function aboutCompany() {
    return (
      <>
        <h1>会社概要</h1>
        <p>props.gaiyou</p>
      </>
    );
  }
  function aboutCompanyOfficer() {
    return (
      <>
        <h1>会社役員</h1>
        <p>props.yakuinn</p>
      </>
    );
  }
  function aboutBusiness() {
    return (
      <>
        <h1>事業内容</h1>
        <p>props.zigyounaiyou</p>
      </>
    );
  }
  return (
    <>
      {aboutCompany()}
      {aboutCompanyOfficer()}
      {aboutBusiness()}
    </>
  );
}


▲この形だと、「Companyコンポーネントの機能を関数に分割して整理する」みたいな意味になります。

 

前者の場合は、以下のように各コンポーネントにpropsをバケツリレーしないといけないので面倒です。

function Company(props) {
  return (
    <>
      <AboutCompany gaiyou={props.gaiyou} />
      <AboutCompanyOfficer yakuinn={props.yakuinn} />
      <AboutBusiness zigyounaiyou={props.zigyounaiyou} />
    </>
  );
}
function AboutCompany(props) {
  return (
    <>
      <h1>会社概要</h1>
      <p>props.gaiyou</p>
    </>
  );
}
function AboutCompanyOfficer(props) {
  return (
    <>
      <h1>会社役員</h1>
      <p>props.yakuinn</p>
    </>
  );
}
function AboutBusiness(props) {
  return (
    <>
      <h1>事業内容</h1>
      <p>props.zigyounaiyou</p>
    </>
  );
}


▲propsを渡すのが面倒くさい。

 

ちなみに前者の場合は以下のように「Componyコンポーネントの中に各コンポーネントを宣言する」みたいな形で書けば、propsを渡さなくて済みますが

function Company(props) {
  function AboutCompany() {
    return (
      <>
        <h1>会社概要</h1>
        <p>props.gaiyou</p>
      </>
    );
  }
  function AboutCompanyOfficer() {
    return (
      <>
        <h1>会社役員</h1>
        <p>props.yakuinn</p>
      </>
    );
  }
  function AboutBusiness() {
    return (
      <>
        <h1>事業内容</h1>
        <p>props.zigyounaiyou</p>
      </>
    );
  }
  return (
    <>
      <AboutCompany />
      <AboutCompanyOfficer />
      <AboutBusiness />
    </>
  );
}


▲コンポーネントの中でコンポーネントを宣言。

 

この形だと、Companyコンポーネントが再レンダリングされるたびにそれぞれのコンポーネントが再定義されちゃいます。

なので例えば、AboutCompanyコンポーネントの中でstateを宣言しても、Companyコンポーネントが再レンダリングされるたびにAboutCompanyコンポーネントが初期化されちゃうので、宣言したstateが意味をなさなくなると思われます。

 

おわり

React
スポンサーリンク
この記事を書いた人
penpen

1991生まれ。WEBエンジニア。

技術スタック:TypeScript/Next.js/NextJS(Express)/Docker/AWS

フォローする
フォローする
penpenメモ

コメント

タイトルとURLをコピーしました