🦁

無理なく始めるゆるっとReact #25 useContext② コンポーネントの分割

2 min read

分割したコンポーネントでuseContextを使ってみる

以下のような構成でコンポーネントを作成しAppProviderでラップしてThirdChildContextを使って値を渡したいと思います。

  • App
    • FirstChild
      • SecondChild
        • ThirdChild

コンポーネントの作成

作成するファイルは4つです(App.jsはすでにある想定です)

  • Provider.js
  • FirstChild.js
  • SecondChild.js
  • ThirdChild.js

Provider.js

Provider.jsのコードは以下の通りになります。

Provider.js
import React, { createContext } from 'react';

// 他のファイルでContextを参照できるようにexport
export const Context = createContext();

const text = 'Providerから受け取ったテキスト';

// Contextオブジェクトを参照できるように`Provider`でラップ
export const Provider = ({ children }) => {
  return <Context.Provider value={text}>{children}</Context.Provider>;
}

App.js

App.js
import { Provider } from './Provider';
import { FirstChild } from './FirstChild';

export default function App() {
  return (
    <>
      // ProviderでタップしているのでFirstChild配下でContextオブジェクトの値が参照できる
      <Provider>
        <FirstChild />
      </Provider>
    </>
  );
};

FirstChild.js

FirstChild.js
import { SecondChild } from './SecondChild';

export const FirstChild = () => {
  return (
    <>
      <p>FirstChild</p>
      <SecondChild />
    </>
  );
};

SecondChild.js

SecondChild.js
import { ThirdChild } from './ThirdChild';

export const SecondChild = () => {
  return (
    <>
      <p>SecondChild</p>
      <ThirdChild />
    </>
  );
};

ThirdChild.js

ThirdChild.js
import React, { useContext } from 'react';
import { Context } from './Provider';


export const ThirdChild = () => {
  const textData = useContext(Context);

  return (
    <>
      <p>ThirdChild:{ textData }</p>
    </>
  );
};

すると画像のようになります。

Provider.jsでvalueに設定した値がThirdChildで受け取り、表示させることができました。

useStateを利用したデータを渡したい

変化するデータを受け渡したい場合も当然出てくると思います。
そんな時は下記のように変更すれば良いと思います。

Provider.js
// useStateを追加する
import React, { useState, createContext } fron 'react';

// Providerの中でuseStateを定義する
export const Provider = ({ children }) => {
  //追加
  const [state, setState] = useState(false);
  
  //valueの渡し方を配列に変更
  return <Context.Provider value={[state, setState]}>{children}</Context.Provider>;
}
ThirdChild.js
// stateとsetStateを定義してContextオブジェクトから受け取った値を代入する
const [state, setState] = useContext(Context);

// click時の処理を追加
const handleClick = () => {
  setState(!state);
};

<>
  <p>ThirdChild:現在のステータス{state ? 'true':'false'}</p>
  <button onClick={handleClick}>state変更ボタン</button>
</>

これでクリックしたらステータスによってtruefalseのテキスト表示が変わるようになったと思います。

Discussion

ログインするとコメントできます