context APIはreactだけで、global stateを実現するためのAPIです。
以下の記事にcontext apiの概要が載っています。
React v16で実装された new Context APIを使って、Reduxへ別れを告げる
基本的に、unstated という、contextAPIを超薄く拡張したライブラリがあるので、実務では生のContextAPIを使うのではなく、unstatedを使うことをオススメしています。
Context APIは神からの祝福です!
学習コストと言うものが存在せず、コード量も少ないので、プロトタイプ製作にとても適しています。
実戦で使っている記事を見ないので、どの様にContext Apiで設計をするのかを記事にしてみました。
それではどの様に実戦的にcontext apiを使うか見てみましょう。
Fluxデザインパターンに従い、reduxから如何に簡単に移行するかに重点を置いて設計します。
まず、componentにどの様にstoreの中のstateが渡されるか見てみましょう。
Context APiを使いProviderとConnectという自作クラスを作り、それによってglobal stateを管理します。
###Proveiderは、 storeをcomponentに渡すための自作クラスです。
Routesはここではアプリのroot componentです。
import React from 'react'
import Routes from './Routes'
import {Provider} from './Redux'
const App = () =>
<Provider>
<Routes />
</Provider>
export default App
Connectはcomponentにstoreを接続するための自作クラスです。
import React, { Component } from 'react'
import { Text, View } from 'react-native'
import { Connect } from '../Redux'
class Home extends Component {
render() {
const {age, increment} = this.props.store
return (
<View>
<Text>{age}</Text>
<Text onPress={() => increment()}>Increment!</Text>
</View>
)
}
}
export default Connect(Home)
それでは、以上の二つの関数を自作していきましょう。
Context APIで Reduxを再現
まず、Context Apiを使うために、Storeと、Provider, connectを作ります。
クラスのstateを、Storeとして扱い、reducerの代わりにsetStateを使います。
import React from 'react'
const Store = React.createContext()
export class Provider extends React.Component {
/*--- store ---*/
state = {
age: 0
}
/*--- reducers ---*/
increment = () => this.setState({age: this.state.age + 1})
/*--- combineReducer ---*/
render () {
return (
<Store.Provider
value={{
...this.state,
increment: this.increment
}}
>
{this.props.children}
</Store.Provider>
)
}
}
/*--- connect ---*/
export const Connect = ChildComponent => props =>
<Store.Consumer>
{context => <ChildComponent {...props} store={context} />}
</Store.Consumer>
Reduxとの比較
超お手軽で、学習コストが低いですね。小規模アプリにはこれ以上ないほどの選択肢ですね。
10ページぐらいのアプリなら問題なく動きます。reduxの1/3のコード量です。
もう私はcontext APIなしでは個人開発ができなくなりました。
ただし、アプリが肥大化していくと、独自ルールが辛くなってきます。拡張性もありません。非同期もrxjsを使っても書きづらいです。
しかし問題ありません。我々にはreduxがいます。
context APIなんてゴミは捨て、reduxへと移行すればいいのです。巨大なエコシステムと堅牢性が我々を幸せにしてくれます。
Redux 万歳!!!