React Context API

React Context API

どうも、ぽっぽです。

GitHub – microsoft\frontend-bootcamp: Frontend Workshop from HTML\CSS\JS to TypeScript\React\Reduxを参考にReactのContext APIについて理解したことを紹介します。

Reactのルールに従うと、アプリケーションが複雑になればなるほどある問題に直面します。

  • データは、コンポーネント間をPropsを使って上のコンポーネントから下のコンポーネントに伝えます。中間に位置するコンポーネントでは使わないけど、更に下のコンポーネントで使う場合も中間のコンポーネントにPropsを渡す必要があります。この問題をprops drillingと言います。
  • 共有データは、ユーザ操作やネットワークの更新によって変化します。コンポーネント間に変更を伝搬するのが困難になります。

この問題を解決する方法の一つにCotext APIがあります。

Todoアプリのコンポーネント間のイメージ

 
interface TodoListProps {
  todos: Todos;
  filter: FileTypes;
  complete: (id: string) => void;
  edit: (id: string, label: string) => void;
  remove: (id: string) => void;
}

<TodoList>はインターフェイスでPropsを上記の型で受け取ります。

<TodoListItem key={id} id={id} complete={complete} todos={todos} edit={edit} remove={remove}></TodoListItem>

そしてこのように、<TodoListItem>Propsを受け渡します。

このような中間のコンポーネントが増えると複雑さが増します。

Context APIでTodoアプリを書いたソース

Reactで作成したTodoアプリにContext APIを使ったソースをこちらからダウンロード出来ます。

このソースはCreate React App · Set up a modern web app by running one command.を使っています。複数のツールを組み合わせて必要な設定なども行ってくれているので便利でした。

npm install
npm start

Todoアプリを動作させる場合、NodeJSのコマンドプロンプトを開いて、ソースをダウンロードして展開した場所(package.jsonファイルがある)に移動します。1行目のコマンドを実行します。package.jsonのパッケージをインストールして、インストールが終わるまで数十秒ほど待ちます。
2行目のコマンドを実行するとブラウザにTodoアプリが表示されます。

終わるときは、コマンドプロンプト上でCtrl + Cをタイプします。

Context APIの使い方

  1. createContextメソッドでContextを作成します。
  2. 作成されたContextProviderを使ってコンポーネントを挟み込みます。
  3. class componentではthis.contextでアクセス出来ます。
  4. function componetではuseContext hookを使ってContextにアクセスします。
// contextを作成
const TodoContext = React.createContext(undefined);

class TodoApp extends React.Component {
  render() {
    // ProviderでPropsを指定
    return (
      <TodoContext.Provider
        value={{
          ...this.state,
          addTodo: this._addTodo,
          setFilter: this._setFilter,
          /* same goes for remove, complete, and clear */
        }}>
        <div>
          <TodoHeader />
          <TodoList />
          <TodoFooter />
        </div>
      </TodoContext.Provider>
    );
  }
}
//class componentでcontextを参照する例
class TodoHeader extends React.Component {
  render() {
    // Step 1: contextでpropにアクセス
    return <div>Filter is {this.context.filter}</div>;
  }
}

// Step 2: componet classのcontextTypeプロパティをセットする
TodoHeader.contextType = TodoContext;
//function componentでcontextを参照する例
const TodoFooter = props => {
  const context = useContext(TodoContext);
  return (
    <div>
      <button onClick={context.clear()}>Clear Completed</button>
    </div>
  );
};

これで必要なデータをContextを経由してアクセス出来るようになり、中間のコンポーネントを経由する必要はなくなります。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

先頭に戻る