【react-redux】私的まとめ

こちらの記事は以下の書籍を参考にアウトプットとして執筆しました。
[React入門 React・Reduxの導入からサーバサイドレンダリングによるUXの向上まで](https://www.amazon.co.jp/React%E5%85%A5%E9%96%80-React%E3%83%BBRedux%E3%81%AE%E5%B0%8E%E5%85%A5%E3%81%8B%E3%82%89%E3%82%B5%E3%83%BC%E3%83%90%E3%82%B5%E3%82%A4%E3%83%89%E3%83%AC%E3%83%B3%E3%83%80%E3%83%AA%E3%83%B3%E3%82%B0%E3%81%AB%E3%82%88%E3%82%8BUX%E3%81%AE%E5%90%91%E4%B8%8A%E3%81%BE%E3%81%A7-%E7%A9%B4%E4%BA%95%E5%AE%8F%E5%B9%B8-ebook/dp/B078XDLL2J/ref=tmm_kin_swatch_0?_encoding=UTF8&qid=&sr=)

#react-redux
ReactとReduxをつなぐ架け橋的なもの

#Container ComponentとPresentational Component
##Container Component
- 責務はReactとReduxの橋渡しのみ
- ここにJSXを書くのは好ましくない

##Presentational Component
- 純粋なReactコンポーネント
- 自分以外のコンポーネントに依存しない

以下は[公式](https://redux.js.org/basics/usage-with-react)から

||Presentational Component|Container Component|
|---|---|---|
|目的|どう見えるか|どう動くか|
|Redux|関係ない|関係する|
|データ取得|props|Reduxのstateをsubscribe|
|データ変更|propsから取得したCallbackを使う|ReduxのactionsをDispatch|
|作成方法|手動|react-reduxのconnect()|

#react-reduxがやっていること
- Provider
- connect

##Provider
これを使うと好きなコンポーネントとStoreを紐付けられる

```javascript
ReactDOM.render(
    <Provider store={store}>
        <MyRootComponent/>
    </Provider>,
    document.getElementById('root')
)
```
storeをMyRootComponentに渡さずProviderに渡している。
MyRootComponentはconnect関数でStoreを受け取る


##connect
Storeを提供する
###mapStateToProps[state,[pwnProps]]
Storeのstateをコンポーネントのpropsに割り当てる関数を指定
returnしたオブジェクトをPropsで受け取れる

##mapDispatchProps(dispatch,[pwnProps])
第1引数のdispatchでコンポーネントからdispatchの概念を隠蔽

ここでdispatchを発行
##mergeProps(stateProps,dispatchPtops,ownProps)
上2つを経たPropsをマージしてコンポーネントに渡す。

#Todoアプリにreact-reduxを導入
```javascript
import { connect } from 'react-redux';
import TodoApp from '../components/TodoApp';
import { inputTask, addTask } from '../actions/tasks';

function mapStateToProps({ task, tasks }) {
  return {
    task,
    tasks
  };
}

function mapDispatchToProps(dispatch) {
  return {
    addTask(task) {
      dispatch(addTask(task));
    },
    inputTask(task) {
      dispatch(inputTask(task))
    }
  };
}

export default connect(mapStateToProps, mapDispatchToProps)(TodoApp);
```
引用：[React入門 React・Reduxの導入からサーバサイドレンダリングによるUXの向上まで](https://www.amazon.co.jp/React%E5%85%A5%E9%96%80-React%E3%83%BBRedux%E3%81%AE%E5%B0%8E%E5%85%A5%E3%81%8B%E3%82%89%E3%82%B5%E3%83%BC%E3%83%90%E3%82%B5%E3%82%A4%E3%83%89%E3%83%AC%E3%83%B3%E3%83%80%E3%83%AA%E3%83%B3%E3%82%B0%E3%81%AB%E3%82%88%E3%82%8BUX%E3%81%AE%E5%90%91%E4%B8%8A%E3%81%BE%E3%81%A7-%E7%A9%B4%E4%BA%95%E5%AE%8F%E5%B9%B8-ebook/dp/B078XDLL2J/ref=tmm_kin_swatch_0?_encoding=UTF8&qid=&sr=)
ここでやっていることは以下の2つ

- mapStateToPropsでStoreにあるtaskとtasksというStateをPropsに渡す
- mapDispatchToPropsで該当ActionをDispatchさせる関数をPropsに渡す

これでこのコンポーネントにはPropsとして次の4つが渡される

- task:inputフォームに入力されたタスク
- tasks:タスク配列
- addTask:タスクを追加する関数
- inputTask:タスクを入力する関数

```javascript
import React from 'react';

export default function TodoApp({ task, tasks, inputTask, addTask }) {
  return (
    <div>
      <input type="text" onChange={(e) => inputTask(e.target.value)} />
      <input type="button" value="add" onClick={() => addTask(task)} />
      <ul>
        {
          tasks.map(function(item, i) {
            return (
              <li key={i}>{item}</li>
            );
          })
        }
      </ul>
    </div>
  );
}
```
引用：[React入門 React・Reduxの導入からサーバサイドレンダリングによるUXの向上まで](https://www.amazon.co.jp/React%E5%85%A5%E9%96%80-React%E3%83%BBRedux%E3%81%AE%E5%B0%8E%E5%85%A5%E3%81%8B%E3%82%89%E3%82%B5%E3%83%BC%E3%83%90%E3%82%B5%E3%82%A4%E3%83%89%E3%83%AC%E3%83%B3%E3%83%80%E3%83%AA%E3%83%B3%E3%82%B0%E3%81%AB%E3%82%88%E3%82%8BUX%E3%81%AE%E5%90%91%E4%B8%8A%E3%81%BE%E3%81%A7-%E7%A9%B4%E4%BA%95%E5%AE%8F%E5%B9%B8-ebook/dp/B078XDLL2J/ref=tmm_kin_swatch_0?_encoding=UTF8&qid=&sr=)

これだとさっきのコードから整形されたオブジェクトがPropsに渡される
先コードではActionCreate,Dispatchもやっているから、inputTaskとaddtaskを呼び出すだけでいい
これでRedux依存が消えて再利用性も高まったという。。。わかんねぇ

また読み直しか。。


#参考
- [Presentational ComponentとContainer Component](https://www.yuuniworks.com/blog/2018-05-18-presentational-component%E3%81%A8container-component/)