React Hooks ✖️ Reduxを使ってみて 自分なりに詰まったところをまとめてみた

自分の作っているサービスで初めてReact Hooks, reduxを使用したので自分が詰まったところをまとめてみました！
**:warning: この記事はReact Hooks, reduxを使う上で、自分が詰まったところについて書いています。
それぞれ個々の説明に関しては公式のドキュメントや別記事をお読みください:warning:**

# 参考にさせていただいた記事
[Redux Hooks によるラクラク dispatch & states](https://qiita.com/Ouvill/items/569384e5c8c7ce78f98e)
[React Hooksでredux / react-reduxでやってたことを色々やってみる](https://qiita.com/terrierscript/items/1516e946dfe91397c229)
[🎉React 16.8: 正式版となったReact Hooksを今さら総ざらいする](https://qiita.com/uhyo/items/246fb1f30acfeb7699da)

# この記事の対象読者
- 私のようなReact超初心者
- React Hooks, redux それぞれは何となくわかったけど一緒に使う方法がわからない方

# 私の開発環境
- macOS Mojave 10.14.6
- Node.js 12.13.0
- React 16.12.0
- create-react-appでアプリの雛形を作成

# 今回作るもの
- ボタンを押したら足したり引いたりできものを作ります

<img width="213" alt="スクリーンショット 2019-12-22 21.54.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348371/6ab69418-b6bc-ffb9-faa2-75224304fdc7.png"><img width="218" alt="スクリーンショット 2019-12-22 21.54.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348371/3c9c2a40-90bd-c27b-ee7b-31162817b300.png">

# actionを作る
`src/actions/action.js`にactionを定義します。
今回は足したり引いたりするだけなのでこの二つでいいでしょう。

```javascript:action.js

export const incrementAction = () => ({
    type: 'INCREMENT',
});

export const decrementAction = () => ({
    type: 'DECREMENT',
});
```

# reducerを作る
`src/reducers/counterReducer.js`にreducersを定義します。
今回は、combineReducersを使いrootReducerでそれぞれのreducerをまとめる形にしました。

```javascript:rootReducer.js
const rootReducer = combineReducers({
    counterReducer,
});

export default rootReducer
```

```javascript:counterReducer.js
const initialState = {
    counter: 0,
};

export default function counterReducer(state = initialState, action) {
    switch (action.type) {
        case "INCREMENT":
            return {counter: state.counter + 1}
        case "DECREMENT":
            return {counter: state.counter - 1}
    }
    return {counter: state.counter}
}
```
**この時注意しないといけない点が、returnする際に連想配列の形にすることです！**
私は`state + 1`や`state.counter + 1`としていたため、うまく受け渡しができていませんでした:sob:

# storeを作る
`react-create-app`で雛形を作った場合`src/index.js`があるのでそこに書いていきましょう！
ReactDOM.renderしているファイルでcreateStoreにrootReducerを渡します。
作成したstoreをProviderに渡して下のコンポーネントでも使えるようにします。

```javascript:index.js
const store = createStore(rootReducer);

ReactDOM.render(
    <Provider store={store}>
        <App/>
    </Provider>,

    document.getElementById('root')
);
```

# 呼び出す
`index.js`で呼び出しているコンポーネントで上で定義したものを呼び出していきます。
`react-create-app`で雛形を作った場合`src/App.js`です！

```javascript:App.js
export default function App() {
    const dispatch = useDispatch() 
    const counter = useSelector(state => state.counterReducer.counter);// 使用するreducerを引数に渡す。
    return (
        <div className="App">
            <p> count: {counter} </p>
            <button onClick={() => dispatch(incrementAction())}>たす</button>
            <button onClick={() => dispatch(decrementAction())}>ひく</button>
        </div>
    );
}
```
**この時注意しないといけない点が、useSelectorに引数を渡す際ちゃんとreducerを指定して渡すことです！**
reducerをrootでまとめているので`useSelector(state => state.counter)`の様にしてしまうと当たり前ですが`undefind`が返ってきてしまいます。

以上で完了です、ページにアクセスしてみましょう。

# まとめ
今回はじめてReact Hooksを使ってみたんですがすごく便利ですね！
まだ出たばかりで資料もすくなかったため、僕の様な超初心者でもわかるように僕が詰まったりしたところを丁寧に書いてみました。

Reactを書くのは初めてなので、この書き方はおかしい！こっちの方がいい！みたいなご指摘がありましたらぜひコメント等いただければと思います。