読者です 読者をやめる 読者になる 読者になる

react.jsでの開発の作業手順まとめメモ 〜 redux + router

はじめに

まだまだよくわかっていないがやっと少し慣れてきたので自分用に作業手順をまとめておく

ディレクトリ構成とベースとなる部分を作る

自分はこんな感じにしてみている。
基本的な構成がこんな感じで、開発するにつれてactions、components、reducers以下にファイルを追加してゆく形なります

.
├── index.js
├── const.js
├── store.js
├── routes.js
├── reducers.js
├── actions
│   ├── xxx.js
│   ├── ・・・
├── components
│   ├── app.js
│   ├── xxx.js
└── reducers
    ├── xxx.js
    ├── ・・・
index.js

エントリーポイントとなるファイル。最初に作ったら基本的にいじらないと思うファイル

import React from "react";
import { render } from "react-dom";
import { Router, hashHistory } from 'react-router';
import { Provider } from "react-redux";
import store from "./store.js";
import routes from "./routes.js";

render((
    <Provider store={store}>
      <Router children={routes} history={hashHistory} />
    </Provider>
), document.getElementById("root"));
const.js

アプリ共通で使う定義はここにまとめる

export const API_URL = "http://example.com/"; // apiのurl
・・・
store.js

そのままだけどstoreをここで作る。
あまりよくわかっていないmiddlewareを追加する際はこのファイルに追加する

import { applyMiddleware, createStore } from "redux";
import reducers from "./reducers.js";
import thunk from "redux-thunk";

const Store = createStore(reducers, applyMiddleware(thunk));

export default Store;
routes.js

ルーティング定義をここで行う。
画面を追加?というかurlを追加するときはこのファイルにもパスとコンポーネントを追加する

import React from "react";
import { Route, IndexRoute } from 'react-router';
import App from "./components/app.js";
import Page1 from "./components/page1.js";
import Page2 from "./components/page2.js";

const Routes = (
    <Route component={App}>
      <Route path="page1" component={Page1} />
      <Route path="page2" component={Page2} />
    </Route>
);

export default Routes;
reducers.js

reducerを分割した場合に、それらのファイルをここでまとめて読み込む。
ので、reducerを追加するたびにこのファイルにも追加してゆく

import { combineReducers } from "redux";
import user from "./reducers/user.js";

export default combineReducers({
    user
});
actionsディレトリ、reducersディレクトリ、componentsディレクト

名前の通り、action、reducer、componentを追加ときにここのディレクトリ以下に追加してゆく

機能(画面)を追加してゆく

基本的に以下の流れの繰り返しになると思う
1. componentを作成
2. routeを追加
3. 必要であればactionとreducerを追加

1. componentを作成
import React from "react";
import { connect } from "react-redux";

export default class Page1 extends React.Component {

    // ロジック部分を実装する
    // (例)何かクリックされた場合
    onClick(e) {
        // 保持する値や画面の状態を変化させる場合はこんな感じでdispatch関数でactionを呼び出す
        this.props.dispatch(sampleAction());
    }
    
    // テンプレート部分を実装する
    render() {
        return (
          <div>Page1</div>
        );
    }
}

Page1.contextTypes = {
    router: React.PropTypes.object
};

// reducerを使う場合はここに使うものを追加してゆく
const connectedPage1 = connect(state => (
    { user: state.user }
))(Login);

export default connectedPage1;
2. routeを追加
・・・
import Page1 from "./components/member/page1.js";
・・・
const Routes = (
    ・・・
    <Route path="page1" component={Page} />
);
3. actionとreducerを追加

自分はmvcのmodelのようなイメージとしている
なのでcomponentからデータの更新が必要な場合に作成する形になるのかと思う

actions/diary.js(★componentから使える形で関数を定義する)

export function add(title, content) {
    return {
        type: "DIARY_ADD",
        diary: { title: title, content: content }
    }
}

export function edit(no, title, content) {
    return {
        type: "DIARY_EDIT",
        no: no,
        daiary: { title: title, content: content }
    }
}

reducers/diary.js

// ここで定義した変数をアプリ全体で参照するイメージ
var initialState = {
    list: [
        {title:"タイトル", content:"内容内容内容"}
    ];
}
export default function diary(state = initialState, action) {

    var _state = Object.assign({}, state);
    switch (action.type) {

    // リストに日記を1件追加する
    case "DIARY_ADD":
        _state.list.push(action.diary);
        return _state;

    // no番目の日記を更新する
    case "DIARY_EDIT":
        _state.list[action.no] = action.diary;
        return _state;

    default:
        return state;
    }
}

で、componentからは以下のように呼びだす。

import { add } from "../actions/diary.js";
・・・

// 更新
this.props.dispatch(add("日記タイトル", "日記の内容"));

// 参照
console.log(this.props.diary.list);

まとめとかいってまとまってない・・・
actions、reducersを作るあたりはもう1度ちゃんと整理したほうが良いかも・・・

以上です