コンテクスト – React
コンテクストは React の簡易なグローバル管理機能です。 props を経由せずに値を操作、反映できることによって多様な props のリレーを行うことなく各所で同一の値を扱えます。
グローバルスコープの値は時として開発者を混乱させるので慎重に用いる必要があります。 React の公式ドキュメントには次の様にあります。
コンテクストは主に、何らかのデータが、ネストレベルの異なる多くのコンポーネントからアクセスできる必要がある時に使用されます。コンテクストはコンポーネントの再利用をより難しくする為、慎重に利用してください。
もし多くの階層を経由していくつかの props を渡すことを避けたいだけであれば、コンポーネントコンポジションは多くの場合、コンテクストよりシンプルな解決策です。
コンテクストはコンテクストの定義(グローバルで管理する値の初期値と書き換え関数)、コンテクストを用いる範囲を決めるプロバイダ、実際に使うコンテクストを呼び出すコンシューマから成ります。正直、複雑です。一度定義したら呼び出しであるコンシューマのみを気にする様に作りたいですし、プロバイダとコンテキストはまとめておきたいです。これを実現するためにコンテクストを完結させるコンポーネントを作り、その子のコンポーネントの中で都度コンシューマを呼び出す作りができます。例は次です。
// @see https://ja.reactjs.org/docs/context.html // ここからコンテキスト定義用ファイル import React from 'react' import {render} from 'react-dom' // コンテクストの初期値を定義 const ThemeContext = React.createContext('light') // コンテクストのプロバイダコンポーネント class ThemeProvider extends React.Component { state = {theme: 'light'} toggleTheme = () => { this.setState(({theme}) => ({ theme: theme === 'light' ? 'dark' : 'light', })) } render() { // プロバイダを配置 return ( <ThemeContext.Provider value={this.state.theme}> <button onClick={this.toggleTheme}>toggle theme</button> {this.props.children} </ThemeContext.Provider> ) } } // ここからコンテキストを呼び出すファイル const styles = { dark: { backgroundColor: 'black', color: 'white', }, light: { backgroundColor: 'white', color: 'black', }, } // コンテキストを呼び出すコンポーネント class App extends React.Component { render() { // コンシューマ直下でコンテキストを使った関数が実行されます return ( <ThemeProvider> <ThemeContext.Consumer> {theme => <div style={styles[theme]}>{theme}</div>} </ThemeContext.Consumer> </ThemeProvider> ) } } render(<App />, document.getElementById('root'))
大雑把に言えばコンテキストを作りこんで、作りこんだコンテキストのプロバイダで props.children をくくる感じです。このつくりでエラー用のダイアログやら何やらを作ると便利に扱えます。