React学んでみた Hooks API createContext useContext


##React

海外で多く扱われているのjsのFW/ライブラリは

React

一強です。

https://note.com/erukiti/n/na654ad7bd9bb

こちらの記事を見ていただけると納得いただけるのではないでしょうか？

自分の目的などと照らし合わせると確実にReactの学習は避けて通れないものになるので
これからキャッチアップを目指していきます。

もちろん現場で学ぶのが一番ではあるので
サクッとキャッチアップした後はアルバイトでも入ってみたい気持ちが強いです。

###Reactの状態管理のベストプラクティス

こちらのサイトに掲載されています。
https://ics.media/entry/200409/

現状3つの手法があるようですね。

###Hooks APIによる　useContext createContext

これらを使うことで状態管理をより楽に実装していきます。
今回のサービスのディレクトリ構成になります。
全て使うわけではありません。

![スクリーンショット 2020-10-11 13.29.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/432086/8614bbfb-3fa1-2c98-da4a-32b429003f06.png)

rootコンポーネントに全体の状態管理のパラメータを渡します。

```App.js
import React, {createContext, useState, useReducer} from 'react'
import ReactDom from 'react-dom'

import {BrowserRouter, Route, Switch} from "react-router-dom";

import GlobalNav from "./GlobalNav";
import Home from "./Home";
import Maxims from './maxim/Maxims'
import Post from "./Post";
import Edit from "./Edit";
import Setting from './Setting'

import SiteContext from "../contexts/SiteContext";
import reducer from '../reducers'

export const MaximContext = createContext()



const App = () => {
    const initialState = {
        maxims: [
            {
                id: 1,
                maxim: 'バレーは上を向くスポーツだ',
                who: '鵜飼コーチ',
                category: 'スポーツ',
                description: 'ハイキュー白鳥戦',
                oneWord: '武者震いしました',
            }
        ]
    }
    const [state, dispatch] = useReducer(reducer, initialState)


    return (
        <BrowserRouter>
            <GlobalNav/>
            <Switch>
                <SiteContext.Provider value={{state, dispatch}}>
                    <Route exact path="/" component={Home}/>
                    <Route exact path="/maxims" component={Maxims}/>
                    <Route exact path="/post" component={Post}/>
                    <Route exact path="/edit" component={Edit}/>
                    <Route exact path="/setting" component={Setting}/>
                </SiteContext.Provider>
            </Switch>
        </BrowserRouter>
    )
}

if (document.getElementById('app')) {
    ReactDom.render(<App/>, document.getElementById('app'))
}

```

以下で全体のstateを渡すためのcontextをimportしてきています。

```App.js
import SiteContext from "../contexts/SiteContext";
```

以下で全体のstateを渡すためのcontextを作成しています。

```SiteContext.js
import { createContext  } from 'react'

const SiteContext = createContext()

export default SiteContext
```

以下で子孫コンポーネントで利用できるように対応しています。

```App.js
<SiteContext.Provider value={{state, dispatch}}>
```

```App.js
    ...
    <BrowserRouter>
            <GlobalNav/>
            <Switch>
                <SiteContext.Provider value={{state, dispatch}}>
                    <Route exact path="/" component={Home}/>
                    <Route exact path="/maxims" component={Maxims}/>
                    <Route exact path="/post" component={Post}/>
                    <Route exact path="/edit" component={Edit}/>
                    <Route exact path="/setting" component={Setting}/>
                </SiteContext.Provider>
            </Switch>
        </BrowserRouter>
     ...
```

### 子コンポーネントで用いる

今回の構成はPOSTコンポーネントで投稿したものを
LIST画面で表示させていくというものになっています。

今回はPOST コンポーネントの箇所は省略させていただきます。

今後改めてまとめます。

※Maximというのは名言という意味で利用しています。

以下のMaximsファイルはmaximを複数持っておりそれらをcomponentに渡します。

```jsx:Maxims.jsx
import React, { useContext } from 'react'

import SiteContext  from "../../contexts/SiteContext";
import Maxim from './maxim'

const Maxims = () => {
    const {state} = useContext(SiteContext);

    console.log(state.maxims);

    return (
        <div>
            <h1>List</h1>
            <div>
                <img src="" alt=""/>
                {state.maxims.map((maxim, index) => (<Maxim key={index} maxim={maxim}/>))
                    }
                )
                })}
                <div>


                </div>
            </div>
        </div>
    )
}

export default Maxims

```

以下で子コンポーネントに値を渡しています。

```maxims.jsx
{state.maxims.map((maxim, index) => (<Maxim key={index} maxim={maxim}/>))
```

以下のmaxim.jsxファイルでは
親のmaximsから受け取ったmaximsをそれぞれ表示させています。

```jsx:maxim.jsx
import React, {useState, useContext, useReducer} from 'react'

const Maxim = ({maxim}) => {

    return (
        <div>
            <div>
                <h3>ID</h3>
                {
                    maxim.id
                }
                <h3>名言</h3>
                {
                    maxim.maxim
                }
                <h3>誰が</h3>
                {
                    maxim.who
                }
                <h3>カテゴリ</h3>
                {
                    maxim.category
                }
                <h3>概要</h3>
                {
                    maxim.description
                }
                <h3>一言</h3>
                {
                    maxim.oneWord
                }
            </div>
        </div>
    )
}

export default Maxim
```
親のmaximsから受け取ったmaximを表示させます。


このような形で親に保存されている値をグローバルに値を用いることができます。


このhooksの状態管理でいいなと思ったのが
渡したい階層にだけ必要な値を渡せるというところですね。

順序としては

+ createContextで必要な値を格納
+ 親にProviderを設置
+ 子コンポーネントでuseContextの引数に作ったcontextを渡す。
+ 受け取った値を描画などで用いる。

の順になります。


自分でまとめてみるとかなり内容が整理されました。
やはり言語化作業は大事ですね。

値の変更（useReducer)に関しては改めて投稿できればと思っています。

これからも学んだことはしっかり言葉にして誰かに伝えられるように発信していきます。