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と呼ぶ?
function addTodo(text) {
return {
type: ADD_TODO,
text: text
}
}
Action(Actionオブジェクト)
- 何をするのかを示すオブジェクト
- typeプロパティ(Actionの識別子)と値のプロパティで構成される
- typeプロパティでreducerと紐づく
{
type: 'ADD_TODO',
text: 'BBBBBBBBB'
}
Store
- 全てのstateを管理するためのオブジェクト
- storeはcreateStoreにreducerを引数にして作成する
- getStateメソッドで状態を取得し, dispatchメソッドで状態を更新する
import { createStore } from 'redux';
import todoApp from './reducers';
let store = createStore(todoApp); // 第二引数で初期stateも設定できる
Store#dispatch
- stateを変える方法はstore#dispatchすること
- dispatchで全てのreducerが呼び出される
- Action関数を噛ましてActionオブジェクトを返す
store.dispatch(addTodo(text))
Reducer(Reducer関数)
- stateとactionをもとにstateを返す
- 中身ではswitch文でactionの識別子の条件分岐文がかかれる
- Reducerはconnect関数を使って、reducerの関数をstoreに登録する
- Store#dispatchされると全てのreducerが実行される
- reducerを複数作った場合combineReducersで一つにまとめる
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など)を受け取ることができるようになる
- ラップしたコンポーネントが対象、子孫コンポーネントには共有されない
ReactDOM.render(
<Provider store={store}>
<AppContainer /> // ここにContainer Componentsを設定する
</Provider>,
document.querySelector('.content')
);
// 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。 |
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