2021年5月22日土曜日

Reactでコンポーネント間のデータ共有がしたい

 Reactは親から子コンポーネントに値を渡す場合、引数(props)として渡すことができる。ただ引数で実装する場合、親から孫や、兄弟で同じ値を参照しようとすると必要もないのに、propsに設定しまくることになるので、メンテンナンス性が良くない。

React ではContext APIを用意しているので、上記のようなケースの場合に使える。


[ドキュメント]

   https://ja.reactjs.org/docs/context.html

[インストール] 

  ※Reactに含まれているuseContextを使うので、Reactが入っていればよし。

[ソース例]

[context/app.js] Context用のファイル
import { createContext } from 'react';
const AppContext = createContext();
export default AppContext;

[App.js] アプリ本体
import AppContext  from './context/app';
import { useState } from 'react';

function App() {
  //authという状態とsetAuthという設定用関数を取得
  let [auth,setAuth] = useState();
  return (
    //AppContextで共有するauthとsetAuthを設定
    <AppContext.Provider value={{"auth":auth,"setAuth":setAuth}} >
    <Sample></Sample>
    </AppContext.Provider>
  );
}

[sample.js] 子コンポーネント
import React,{useContext} from 'react';
import AppContext  from './context/app';
function App(){
    //useContextでAppContextの状態を取得
    let app_context=useContext(AppContext);
    //Contextに値を設定
    app_context.setAuth({user_id:1});
   //参照
    console.log(app_context.auth);//{user_id:1}
    
    return (
        <div></div>
    );
}
export default Sample;


[ソース内での書き方]

  1.  createContextでContextを生成する。
    他のコンポーネントにimportするため、外部ファイルにしておく。
    適当に名前を付けてたContext用の変数にcreateContext()の戻り値を設定する。
      const AppContext = createContext();
    他のソースで読みこんだ時にアクセスできるように宣言をしておく
      export default AppContext;

  2. 共有したい範囲のコンポーネント上位に、ContextのProviderを設置する。

    定義したContextにはProviderが標準で用意される。
    定義したContextに合わせてタグを作る
    <AppContext.Provider value={オブジェクト}></AppContext>
    ソース例(App.js)では、面倒なのでuseState()で管理する値と、変更用の関数を用意して、それらをContentに設定している。

  3. Context.Consumer側での値の参照
    上位はPoviderで、受け取る側はCunsumerというらしい。
      関数コンポーネントの場合はuseContext()フックが使えるので、意識しなくても大丈夫。

     利用する場合は、useContext(定義したContext)で利用するContextを取得する。
     ソース例では、AppContextとしているので、useContext(AppContext)と記述することになる。
    Contextが取得できれば、あとは、共有した要素に直接以下のようにアクセスできる
        Context.共有値
    ソース例では、値保持用のauthと変更用のsetAuthという関数型の値を共有しているので、
        app_context.auth
        app_context.setAuth({user_id:2}) 
    といったようにアクセスできる。

0 件のコメント: