ReactでReduxやContextAPIを使わず、親コンポーネントに手続きを書かず、Providerも作らず、コンポーネント間通信する

2 min read読了の目安(約2100字

コンポーネント間のデータのやりとり

Reactの序盤で障害となるのがコンポーネント間のデータのやりとりです。コンポーネントを超えてデータをやりとりしようとすると、親コンポーネントにstateを作って、値やdispatchを各コンポーネントに配る必要があります。もしくはContextAPIReduxの利用という流れになっていくわけですが、導入時に書かなければいけないコードが増大するので、それなりの負担が待っています。

このあたりを簡単にする方法を紹介します。

※利用するに当たっては
yarn add -D @react-libraries/use-global-state
などのコマンドでパッケージをインストールする必要があります。

今回作ったコードは以下の場所にあります
https://github.com/SoraKumo001/use-global-state-sample01

使用例紹介 BMIを計算するプログラム

※Next.jsを使用していますが、useGlobalState自体は素のReactでも動作します

src/pages/index.tsx

import { useGlobalState } from '@react-libraries/use-global-state';
import React from 'react';

const Tall = () => {
  const [value, setValue] = useGlobalState('tall', '170');
  return (
    <div>
      Tall:
      <input
        value={value}
        onChange={(e) => {
          setValue(e.target.value);
        }}
      />
    </div>
  );
};
const Weight = () => {
  const [value, setValue] = useGlobalState('weight', '60');
  return (
    <div style={{ display: 'flex' }}>
      Weight:
      <input
        value={value}
        onChange={(e) => {
          setValue(e.target.value);
        }}
      />
    </div>
  );
};

const Bmi = () => {
  const [tall] = useGlobalState<string>('tall');
  const [weight] = useGlobalState<string>('weight');
  return (
    <div>
      {isNaN(Number(tall)) || isNaN(Number(weight))
        ? 'Error'
        : `BMI:${Math.floor((Number(weight) / Math.pow(Number(tall) / 100, 2)) * 100) / 100}`}
    </div>
  );
};

const Page = () => (
  <>
    <Bmi />
    <Tall />
    <Weight />
  </>
);
export default Page;

useGlobalStateは名前の通りuseStateのグローバル版Hookです。コンポーネントを飛び越えてデータ共有が可能です。使用するに当たってはReduxやContextAPIにあるようなProvider相当のコンポーネントを上位に持つ必要はありません。いきなり書いていきなり使えます。イキナリ素敵です。

useGlobalStateは複数の場所で異なる初期値が設定されていた場合、最初に実行された初期値が採用されます。また、初期値無しを通った後に初期値ありを通った場合は、その初期値を利用してコンポーネントが再検証されます。

その他@react-libraries/use-global-stateにはmutate関数を用意してあり、useGlobalStateの設置コンポーネント外からデータを設定することも可能です。データは送るけれど自分自身は再検証の対象にならないコンポーネントが作成可能です。

テスト実行時、保存データをクリアするためには@react-libraries/use-global-stateからresetを取り出して実行します。

楽ちん

データやイベントのやりとりのために余計なコードを書かなくて済むのでとても楽ちんです。