コンテキスト
コンテキストを使用すると、途中のすべてのコンポーネントに props 経由で渡すことなく、ツリーの奥深くにある子に値を渡すことができます。非常に一般的なユースケースは、テーマ設定です。簡単に言うと、コンテキストは Preact で pub-sub スタイルの更新を行う方法と考えることができます。
コンテキストを使用するには、2 つの方法があります。新しい `createContext` API とレガシーコンテキスト API です。2 つの違いは、レガシー API は、途中のコンポーネントが `shouldComponentUpdate` でレンダリングを中止した場合、子を更新できないことです。そのため、常に `createContext` を使用することを強くお勧めします。
createContext
まず、渡すことができるコンテキストオブジェクトを作成する必要があります。これは `createContext(initialValue)` 関数を使用して行います。コンテキスト値を設定するために使用される `Provider` コンポーネントと、コンテキストから値を取得する `Consumer` コンポーネントが返されます。
`initialValue` 引数は、コンテキストにツリーの上部に一致する `Provider` がない場合にのみ使用されます。これは、ラッピング `Provider` を作成する必要がないため、コンポーネントを分離してテストする場合に役立ちます。
const Theme = createContext('light');
function ThemedButton(props) {
return (
<Theme.Consumer>
{theme => {
return <button {...props} class={'btn ' + theme}>Themed Button</button>;
}}
</Theme.Consumer>
);
}
function App() {
return (
<Theme.Provider value="dark">
<SomeComponent>
<ThemedButton />
</SomeComponent>
</Theme.Provider>
);
}
REPL で実行コンテキストを使用するより簡単な方法は、useContext フックを使用することです。
レガシーコンテキスト API
レガシー API を含めているのは、主に下位互換性のためです。`createContext` API に置き換えられました。レガシー API には、`shouldComponentUpdate` で `false` を返すコンポーネントが間に存在する場合に更新がブロックされるなど、既知の問題があります。それでも使用する必要がある場合は、読み続けてください。
コンテキストを介してカスタム変数を渡すには、コンポーネントに `getChildContext` メソッドが必要です。そこで、コンテキストに格納する新しい値を返します。コンテキストには、関数コンポーネントの 2 番目の引数またはクラスベースのコンポーネントの `this.context` を介してアクセスできます。
function ThemedButton(props, context) {
return (
<button {...props} class={'btn ' + context.theme}>
Themed Button
</button>
);
}
class App extends Component {
getChildContext() {
return {
theme: 'light'
}
}
render() {
return (
<div>
<SomeOtherComponent>
<ThemedButton />
</SomeOtherComponent>
</div>
);
}
}
REPL で実行