Edited at

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

More than 1 year has passed since last update.

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を変える構造


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を使うと幸せになれる

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