ReactとReduxちょっと勉強したときの📝

React使えばユニバーサルアプリが簡単に作れそうだったし、MVCよりReduxが面白そうだったので、
勉強したときの個人的memo

# ReactのStateとPropsのちがい

|名前|From|使い方|
|---|---|---|
|Props|親| コンポーネントの属性。つまり、コンポーネントのinterface、React.propTypesで宣言的に記述する。immutable|
|State|自身|コンポーネントの状態。たくさんのstateを持つ場合は、複雑とも言える。mutable|
|Refs|自身|同一コンポーネント内の参照。renderメソッド内で、ref属性により名前をセットする。ReactDOM.findDOMNodeとセットで使用する|

# Redux/Flux
- アーキテクチャーの名前
- 処理が一方方向の流れに成る
- 流れは以下の画像のような感じ
- state（現状）とaction（行動）を元にstateを変える構造

![](https://blog.kazu69.net/images/2016/02/04/redux.png)

# Action Creator(Action関数)
- actionオブジェクトを返す関数
- またの名をdispatcherと呼ぶ？

```:action/index.js
function addTodo(text) {
  return {
    type: ADD_TODO,
    text: text
  }
}
```


# Action（Actionオブジェクト）
- 何をするのかを示すオブジェクト
- typeプロパティ（Actionの識別子）と値のプロパティで構成される
- typeプロパティでreducerと紐づく

```:js
{
  type: 'ADD_TODO',
  text: 'BBBBBBBBB'
}
```


# Store
- 全てのstateを管理するためのオブジェクト
- storeはcreateStoreにreducerを引数にして作成する
- getStateメソッドで状態を取得し, dispatchメソッドで状態を更新する

```:js
import { createStore } from 'redux';
import todoApp from './reducers';
let store = createStore(todoApp); // 第二引数で初期stateも設定できる
```

# Store#dispatch
- stateを変える方法はstore#dispatchすること
- dispatchで全てのreducerが呼び出される
- Action関数を噛ましてActionオブジェクトを返す

```:js
store.dispatch(addTodo(text))
```


# Reducer(Reducer関数)
- stateとactionをもとにstateを返す
- 中身ではswitch文でactionの識別子の条件分岐文がかかれる
- Reducerはconnect関数を使って、reducerの関数をstoreに登録する 
- Store#dispatchされると全てのreducerが実行される
- reducerを複数作った場合combineReducersで一つにまとめる

```:js
function addTODO(state, action) {
  if (action.type != ADD_TODO) {
    return newState;
  }
}
```

# react-reduxを使ったview（react）との連携
- providerとconnectメソッドを使用する
- providerは親のドムとstoreプロパティを持つ
- connectはstateとdispatcherを引数にAppのporpsにバインドしてAppを返す

# react-redux#connect
- connectメソッドを使って、**共通のprops**を持つ親コンポーネントを作れる
- connectメソッドを使ってラップされたコンポーネントはstoreのメソッド(dispatchなど)を受け取ることができるようになる
- ラップしたコンポーネントが対象、子孫コンポーネントには共有されない



```app.js
ReactDOM.render(
  <Provider store={store}>
    <AppContainer /> // ここにContainer Componentsを設定する
  </Provider>,
  document.querySelector('.content')
);
```

```container/app.js
// Connect to Redux
// この関数は第一引数はstore.getState()の結果を第一引数に、このContainer componentへ渡されたpropsを第二引数にして呼び出され、
// これらのstateとpropsを使って子のPresentational componentにpropsとして渡す値を生成する
function mapStateToProps(state, ownProps) { 
  return {
    text: state.text,
  };
}
// この関数はは，store.dispatchを第一引数にして呼び出される関数で、
// dispatchを使って子のPresentational componentにpropsとして渡す関数を生成する
function mapDispatchToProps(dispatch) {
  return {
    onClickButton(text) { // このonClickButtonというdispacherにTODOAppのコンポーネントのthis.props.onClickでアクセス可能
      dispatch(addTodo(text)); // actionCreatorの関数を使用してactionをdispatchに返してそれを実行している。その後、createStoreで登録したreducerに処理が移る
    },
  };
}
const AppContainer = connect(
  mapStateToProps,
  mapDispatchToProps
)(TODOApp);
```

# action関数の自動追加
- action関数を作っていちいちconnectに追加するNOVAめんどくさいときは
- bindActionCreatorsを使うと幸せになれる

```js
import * as actions from '../actions/'
export default connect(state => ({
  state: state.text
 }),
 (dispatch) => ({
  actions: bindActionCreators(actions, dispatch)
 })
)(TODOApp);
```

# Componentの種類について
|component|memo|
|---|---|
|Provider component|react-reduxから提供されたpropにstoreを持つcomponent|
|Container(Smart) component|ロジックをメインに記述する。Provider Componentの直下に配置する。フォルダ名はcontainer。|
|Presentational(Dumb) component|表示をメインに記述する。Container Componentの配下に記述する。フォルダ名はcomponent。|

```:presentional_component.js
import React from 'react'

export default class extends React.Component {
    render() {
        const {
            text,
            onClickButton, // connectでバインドシているため、action関数をthis.propsからアクセス可能
        } = this.props

        return (
            <div>
                <p>{text}</p>
                <button onClick={onClickButton}>追加!</button>
            </div>
        )
    }
}
```


##処理の流れ
- StoreにReducerを登録する
- Provider ComponentにStoreを登録する
- Connectを使ってContainer Componentにaction関数を登録する
- viewのイベントが発生する
- Container Componentのイベント処理からstoreのdispatcherとaction関数を呼び出す
- Storeに登録したreducerを経由してstateを変更する
- stateの変更がviewに伝達して描写が変わる

# 参考文献
http://qiita.com/kiita312/items/49a1f03445b19cf407b7
http://qiita.com/shohey1226/items/0de513a8b5b863286eb2
http://qiita.com/yasuhiro-okada-aktsk/items/9d9025cb58ffba35f864
http://qiita.com/ichiroc@github/items/ea66a5ce6fd6a8a2fe43
http://qiita.com/kobanyan/items/5709fabcceb71a086507
http://redux.js.org/docs/api/Store.html
https://github.com/reactjs/react-redux/blob/master/docs/api.md#api
http://qiita.com/yuichiroTCY/items/a3ca7d9d415049d02d60
http://hisasann.github.io/2015/12/08/electron-react-redux-boilerplate/
http://blog.andgenie.jp/articles/1021
http://post.simplie.jp/posts/69