prop-drilling問題
Reactコンポーネントの構造はツリーのようなものです。各子には親が1つだけあり、全員がメインルートコンポーネントに接続されています。この構造のおかげで、一方向の流れしかありません。propsを利用することで親から子、子から親に渡すことができます。 多数のコンポーネントを介してデータを渡す必要がある場合、面倒になり、それをprops-drilling問題が発生します。
props-drilling問題を解消するのにReact Contextが役に立ちます。
以前までの状態管理
- ちょっと前まではreduxを利用して下記のような宣言をしてデータを持ちまわっていた
import { connect } from 'react-redux'
class EventsIndex extends Component {
}
// プロバイダから渡された状態
const mapSateToProps = state => ({ events: state.events })
const mapdispatchToProps = { readEvents }
// デコレートする
export default connect(mapSateToProps, mapdispatchToProps)(EventsIndex)
ReactContext
- アプリで一部のデータをグローバルにする必要がある場合、またはアプリ構造の深くネストされた異なるレベルのいくつかのコンポーネントでそれらを使用する場合は、React Contextを使用するのが便利です。ReactContextを利用することで、React Appツリー構造の各レベルのデータにアクセスできます。
コンテキストを作成するには?
コンテキストを作成するcreateContextを利用して、Reactライブラリからメソッドをインポートして呼び出すことができます。
/contexts/AppContext.jsファイルを作成します
import { createContext } from 'react'
const AppContext = createContext()
export default AppContext
useReducer
import {
CREATE_EVENT,
DELETE_EVNET,
DELETE_ALL_EVNETS
} from '../actions'
const events = (state = [], action) => {
switch (action.type) {
case CREATE_EVENT:
(省略)
return [...state]
case DELETE_EVNET:
(省略)
return [...state]
case DELETE_ALL_EVNETS:
return []
default:
return state
}
}
export default events
利用方法
import React, { useReducer } from 'react';
import reducer from '../reducers'
import AppContext from '../contexts/AppContext'
import reducer from '../reducers'
const App = () => {
const [state, dispatch] = useReducer(reducer, [])
return (
<AppContext.Provider value={{ state, dispatch }}>
<div className="container-fluid">
<EventForm />
<Events />
</div>
</AppContext.Provider>
)
}
おまけ
下記のコースを購入して覚えると習得が容易にできると思います。独学だけだと限界がある人はこちらがお勧めです。 - React Hooks 入門 - Hooksと Redux を組み合わせて最新のフロントエンド状態管理手法を習得しよう! https://www.udemy.com/course/react-hooks-101/
- 上記のソースは下記のgithubで確認できます。 https://github.com/DiveIntoHacking/react-hooks-101