クイック エンジニアリングブログ

株式会社クイック Web事業企画開発本部のエンジニアリングチームが運営する技術ブログです。

久しぶりにReactでアプリを作った感想

こんにちは。新卒2年目ソフトウェアエンジニアのほっしーです。今年度からプロジェクトを異動して業務でReactを使うようになりました。今回は勉強も兼ねてこちらの記事でVue2からVue3に書き換えたWebアプリをReactで作り直してみました(簡易的な掲示板アプリでログイン、投稿、プロフィール編集などの機能が実装されています)。

プロジェクト異動時点の私は
・関数コンポーネントを使ったことはある
・useEffect, useStateなどコードを書く上で必須の部分は知っている
・Context, カスタムフックなどの知っていればより良いコードが書ける部分は知らない
ぐらいの知識量でした。
今回はそんな私がContextとカスタムフックを使って感動した話とVueからReactに書き替えた感想を語らせていただきます。

Context

親コンポーネントから子コンポーネントに値や関数を渡す際には通常はpropsを使います。1つ下の子コンポーネントにpropsを渡すだけなら問題ないのですが、親から2つ、3つ下のコンポーネントに値を渡すとなると親→子→…→子とバケツリレーのような形になってしまいます。その際、Contextを使うことで離れたコンポーネント同士でも値・関数を共有しやすくなります(図1)。

図1 props(左)とContext(右)で親から子へ値・関数を渡すイメージ
詳しい説明は割愛しますが
1.createContextで図1の「値・関数」にあたる部分のコンテクストを作成
2.親コンポーネントをProviderで囲む
で親コンポーネント配下のコンポーネントはどこからでも1.の値・関数を使えるようになります。Providerで囲んだ範囲外では使えないので、もしContext関連のエラーが発生した際にはその点も確認してみましょう。

Vue2でアプリを作っていた頃ははmixin、Vue3ではComposition APIを使ってログイン情報を保持しておりましたが、ReactのContextでも同じ感覚で任意のコンポーネントから参照可能な値を保持することができました。Contextを知った今となってはpropsでバケツリレーをしていたあの頃の生活には戻れそうにありません。大変便利です。ただし、Contextの使用箇所では参照している・していないに関わらずContext内のstateが更新されると再レンダリングされます。不要な再レンダリングが発生する原因になるためご注意ください。

カスタムフック

フックとはstateなどをclassを書かずに使える機能のことです(useState, useEffect など)。これらのフックを独自に作成したものがカスタムフックです。

例えばProfileコンポーネントで以下のようにログインユーザーの情報を取得していたとします。

// Before

export const Profile: React.FC = () => {
  const [loginUser, setLoginUser] = useState({});

  useEffect(() => {
    axios.get('/api/user', {
      params: {
        userId: 'xxxxxxx'
      }
    }).then((response) => {
      setLoginUser(response.data)
    })
  }, []);

  return (
    // 見た目に関する処理
  );
};

上記の取得処理をカスタムフック(今回の場合はuseFetchLoginUser)で書くと以下のようになります。

// After

export const Profile: React.FC = () => {
  const [loading, loginUser] = useFetchLoginUser();

  return (
    // 見た目に関する処理
  );
};

useEffect内で取得してsetLoginUserしていた部分を丸々useFetchLoginUser.tsxの中に移動した感じです。もちろんuseFetchLoginUser内ではBeforeのコードと似たような処理が行われているのですが、取得に関する処理を切り出したことで呼び出し元の方のコンポーネントはかなりすっきりしたことがわかります。また、useFetchLoginUserを呼び出せば取得処理を何度も書き直す必要が無くなり、コンパクトで再利用のしやすいコードになりました。

全体を通して

入社後にVueを学び始めた頃から感じてはいたのですが、今回改めてReactとVueには似ている部分が多くあるなと思いました。
例えば1つのコンポーネントの中に
・状態を保持する部分があり、値が更新されると再レンダリングされる
・コンポーネント呼び出し時に関数を1回だけ実行する書き方ができる
・大まかに見ると処理を書く部分と見た目を書く部分に分かれている
などが挙げられます。
以下の画像は左がVue、右がReactで書かれたプロフィール編集画面のコンポーネントなのですが、上下で処理と見た目のコードの位置が入れ替わっている点を除けばほぼ同じ内容になっています。皆さんの中にも「Vueは書けるけどReactは怖くて手が出せていない...」という方がいらっしゃいましたら、想像しているよりも学習コストは低いと思うのでこれを期にぜひ勉強してみてください!

図2 プロフィール編集画面用コンポーネントの比較
個人的にはReactの方が上から順にコードを読みやすいので気に入っています(上からimport、props、色々処理があって最後にreturnの順で)。少ししか触ったことがありませんが、Vue3になってその辺りの構成がReactに似てきたのでVue3も読みやすくて良いなと思っています。