LoginSignup
102
105

More than 5 years have passed since last update.

React/Reduxを管理画面に使った話

Last updated at Posted at 2016-07-07
1 / 47

自己紹介

  • @adwd118
  • adwd :octocat:
  • 株式会社ビズリーチ
    • スタンバイ事業部
  • Web歴1年
  • サーバーサイドエンジニア?

React/Redux入門やりました

スクリーンショット 2016-07-07 18.03.28.png


求人検索エンジン スタンバイ


スタンバイ

スクリーンショット 2016-07-04 18.07.31.png


スタンバイ

スクリーンショット 2016-07-07 18.05.46.png


:exclamation: 社内向け管理画面

  • スタンバイの社内向け管理画面でReact/Reduxを使った
  • スタンバイ本体ではない
    • SPA的要素はあまりない
    • パフォーマンス、セキュリティなどそこまで気を使ってない

コンテンツ

  • React/Fluxについて
  • 管理画面の構成
  • React/Reduxを使った感想

React

react.png


React

  • javascriptでUIを構築するライブラリ
    • (MVCのV)
  • コンポーネント指向
  • js-centric
    • ほぼjsの中で完結する
  • Flux
    • 単方向データフロー

Flux

  • ViewはStoreからデータ(状態)を受け取って表示するだけ
  • Storeの状態を変更するのはActionのみ

flux-simple-f8-diagram-with-client-action-1300w.png


Flux

  • わかりやすい
  • ActionとそれによるStoreの変化を追跡すれば良い

flux-simple-f8-diagram-with-client-action-1300w.png


サーバーサイドっぽい?

  • View = html or json
  • Store + Dispatcher = DB
  • Action = リクエスト
  • サーバーサイドエンジニアが片手間でフロントを構築するのにも向いている

flux-simple-f8-diagram-with-client-action-1300w.png


社内向け管理画面

スクリーンショット_2016-06-22_17_39_13.png


普通(?)の管理画面

  • なんかのリストを表示
    • そこにアイテムを追加・編集・削除
    • モーダルダイアログだしたり
  • たまにグラフを表示したり
  • SPAではない
    • けどReact/Redux使っちゃった :joy:

管理画面にReact?

  • 2015年末の状況+勢い :innocent:
jQuery
でっかいフォーム・表がつらい :skull:
Angular 1
そのうち全然違う2が出る
Angular 2
まだbeta

構成

  • React, Redux
    • react-redux, react-router, redux-form, redux-thunk
  • babel
  • browserify
  • mocha, power-assert, enzyme, sinon, nightwatch
  • react-bootstrap, AdminLTE
  • バックエンド
    • Scala/Play Frameworkでjson APIサーバー

React/Reduxを使った感想


React/Reduxを使った感想

  • 注意: 個人的な感想です!

Pros/Cons


Pros: わかりやすい :joy:

  • Reactコンポーネント
    • コンポーネントの中にhtmlのテンプレートとロジック(state, props)がある
    • jsファイルを一つ見ればそのコンポーネントがわかる

Pros: わかりやすい :joy:

  • Reactコンポーネント
    • 管理・操作するのはstate, propsでただのJSONオブジェクト
      • DOMを意識しなくて良い :innocent:
    • js(+css)を見てJSONを管理するだけ...ただのプログラミングだこれ!

Pros: わかりやすい :joy:

  • Flux/Redux
    • 単方向データフロー
    • Action -> Reducer -> Store -> View
    • Actionとその結果のStoreを気にすれば良い
    • Redux DevToolでAction,Storeを時系列に表示、リプレイも可能
    • 書き方がほぼ決まっている

Cons :cry:

  • 書くコードの量は多い(主にRedux)
  • jsxがキモい・・・?
    • すぐ慣れる、むしろ好き
  • npm, browerify(webpack)の知識
    • 最近sourcemapが壊れててヤバイ :joy:
  • React/Reduxの学習コストは少なからずある
    • jQuery < React/Redux < Angular ?

Cons :cry:

  • Reactでフォームが楽に書けるかというとそうでもない
    • redux-formでそこそこ楽になった
    • フォーム周りはAngularとかのほうが楽?

すげー辛い!ってことはそんなにない :innocent:


Reduxいらなかったかも


Reduxいらなかったかも

  • SPAではないので、アプリケーションとして管理すべき状態はあまりない

Reduxいらなかったかも

  • Fluxが必要かどうかわからないなら、必要ではない
    • by React初期からの開発者: Pete Hunt
  • Reactだけで問題がないなら、Reduxは必要ない
    • by Redux開発者 Dan Abramov
  • 人の話は聞こう :joy:

Reduxいらなかったかも

  • 状態を管理するコンポーネント、表示を行うコンポーネントの分割をちゃんとやればReact, React-routerで十分だった
  • Presentational and Container Component
  • とはいえRedux Devtoolは便利

Storeの設計ミス


Storeの設計ミス

  • URLのパスとStoreの分割を一致させた
    • users, user/:id, user/:id/edit
{
   "listUsers": ...,
   "showUser": ...,
   "editUser": ...,
   ...
}

Storeの設計ミス

  • チームでの分業には良い(?)
  • 同じ情報を複数の場所で持ってしまう
  • 不必要に巨大なStoreに :joy:

Store = 状態 + エンティティ

状態
例: inputに入力している文字列
エンティティ
例: APIから受け取ったデータ

これを...

{
  "todo": {
    "edit": { "text": "sh", "user": "tom" },
    "list": [
      { "text": "eat", "user": "tom" },
      { "text": "sleep", "user": "tom" }
    ]
  }
}

こうじゃ!

{
  "todo": {
    "edit": { "text": "sh", "user": "tom" }
  },
  "entities": {
    "todo": {
      1: { "text": "eat", "userId": 1 },
      2: { "text": "sleep", "userId": 1 }
    },
    "user": {
      1: "tom",
      2: "bob"
    }
  }
}

エンティティの管理

  • normalizr, reselect
    • REST APIからのデータを正規化する
    • 参照: Dockerの中の人が書いたgitbook
  • 毎回API叩くわけにもいかないのでキャッシュ的な実装も必要?
    • 社内向け管理画面なんで毎回叩いてます :joy:
  • Relay, Falcor
    • 大規模なら検討の価値アリ?
  • このへんのベストプラクティス教えて下さい :pray:

コンポーネントの粒度


コンポーネントの粒度

  • 初期は1画面1コンポーネントで作っていた
  • 巨大なstate、巨大なprops
    • それに合わせた何でも返すAPI
  • 後から見ると読みづらくメンテナンス性 :arrow_down:
  • 再利用性のないコンポーネント、API

コンポーネントの粒度

  • 意味がある単位で小さく分ける
    • それに応じた小さなAction, Reducer, API
    • 小さく分けて組み合わせる(Unixっぽい)
  • 読みやすさ、テストの容易さのためもなるべく小さいほうがよいのでは

テストライブラリの充実


テストライブラリの充実

  • enzyme, sinonを使えばコンポーネントに対するユニットテストは簡単に書ける

参照: ReactでTDD(テスト駆動開発)を始めよう : 環境構築からテスト作成、機能実装までの詳解ガイド


enzyme テストコード例

  • インスタンスメソッドの実行、state変更の確認
it('adds items to todo list', () => {
  const wrapper = shallow(<TodoList />)
  wrapper.instance().addTodo('learn enzyme')
  assert.deepEqual(
    wrapper.state('todos'), ['learn enzyme']
  )
})

enzyme テストコード例

  • イベントのシミュレート、コールバック関数実行の確認
it('callback should be called', () => {
  const onButtonClick = spy()
  const wrapper = shallow(
    <TodoItem onRemove={onButtonClick} />
  )

  wrapper.find('input').simulate('click')
  assert(onButtonClick.calledOnce)
})

まとめ


まとめ

  • 社内向け管理画面でReact/Reduxを使った
  • よかった
    • 主にわかりやすさ
    • サーバーサイドエンジニアでもいける
  • とはいえ書くコードは多めになる

まとめ

  • React
    • コンポーネントを小さく分けて可読性・テスタビリティを上げる
    • テストはenzymeで書きまくれる
    • React-Bootstrap + AdminLTEで見た目が整った画面をサッと作れた
  • Redux
    • 単方向データフローのわかりやすさ
    • Storeはエンティティをキャッシュする役割もあることを考慮して設計する
  • まだまだ学ぶことは多い・・・!
    • けど面白い :joy:

おわり

102
105
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
102
105