LoginSignup
160
141

More than 5 years have passed since last update.

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

Last updated at Posted at 2016-09-27

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

160
141
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
160
141