Webエンジニアの備忘録

およそ自己の作業メモとして残しております。

フロントエンド初心者がReactによるSPAを構築するに至るメモ

はじめに

最近Javascriptを用いたフロントエンド開発に従事することになり、取り急ぎ敷居が低そうなReactjsに飛びつきました。 jqueryを弄る程度で知識的に止まっていたので、学習は相当ステップを刻むことになってしまいました…

最近ようやくたたき台的なものが書けてきました。 これを一度節目に、私くらいのレベルからReactを始める人のため、バックエンドエンジニアからの理解のため、そして何より自分が忘れないためにここまでの流れを一旦まとめます。

学習の変遷(やってみたこと)

1. Reactチュートリアル

https://facebook.github.io/react/docs/tutorial-ja-JP.html

JSXに触れる

return <div>ほげほげ</div>
 ↓
return (
    <div>ほげほげ</div>
);

state/propsを理解する

  • propsはプロパティ、stateが状態を表す。
  • 親のstateをsetStateで更新し子のpropsが変更される、というのが基本的なアクション。

gulp導入

  • jsxの利用で必ずbabelifyが必要になるので、さっさと導入したほうがいい。
    • 以下は最低限な感じのgulpfile.jsサンプルです。(watchも導入したほうがいい)
var gulp        = require('gulp');
var pkg         = require('./package.json');
var browserify  = require('browserify');
var babelify    = require('babelify');
var source      = require('vinyl-source-stream');

gulp.task('js', function() {
  browserify({
      entries: './src/index.jsx',
      extensions: [".js", ".jsx"],
      debug: true
    })
    .transform(babelify)
    .bundle()
    .pipe(source('bundle.js'))
    .pipe(gulp.dest('./public/assets/js/'));
});

gulp.task('default', ['js']);

2. ES6で書き直してみる

参考にしたサイト

eslint

  • eslintを導入しコードを機械的にチェックさせる。
    • コーディングに安心感が出る。ソロ開発は検証者がいないので、変な書き方にきづけるよう入れておくと吉。
    • わたしはVisualStudioCode(VSC)で開発を行っています。フリーな上、非常に使いやすいです。
  • VSC + eslint
    • VisualStudioCode
    • eslintプラグイン(VSC内から追加) f:id:tak_taniguchi:20160917205230p:plain
    • eslintrc.json / .eslintignore ファイルの作成
      • jsを書いているディレクトリ下にてeslint --initを実行するとeslintrcが作られます。
      • .eslintignoreは対象にしたくないファイル(gulpfile.jsなど)を記載できます。
      • わたしの設定も晒しておきます。
{
    "env": {    // (windowなど)特定のグローバル変数を許可したりします
        "browser": true,
        "node": true
    },
    "extends": "airbnb",    // React界隈ではairbnbのコードスタイルがわりとメジャーのようです
    "plugins": [
        "react",
        "jsx-a11y",
        "import"
    ]
}

ファイル構成の見直し、クラス分割

  • クラス単位でのファイル分割
    • ページ構成要素をcomponentsとし、ディレクトリを用意しました。
    • ページ構成要素が1つの場合はそのままファイル名に、複数の場合はディレクトリを作成しindex.jsを用意しました。
      • 外部参照時にcomponents/Mainと呼び出すことで、Mainがcomponent的に分割された際もcomponents/Main/index.jsxを作れば同じように呼び出せるため。
─src
  └jsx
    └components
      └Main.jsx       // components/Mainと呼びだす
      └Todos
        └index.jsx    // components/Todosと呼びだす
        └List.jsx      // Todosページの構成要素
        └Detail.jsx   // Todosページの構成要素
  • 共通クラスの用意
    • コンポーネントも使いまわすものはsharedディレクトリにまとめました。
      • とはいえ、この段階ではテンプレートエンジンにあるinclude的に使う程度です。
─src
  └jsx
    └components
      └shared
        └Header.jsx
        └Footer.jsx

3. ルーティングの考慮

React Routerの導入

import React from 'react';
import { render } from 'react-dom';
import { Router, Route, IndexRoute, useRouterHistory } from 'react-router';
import { createHashHistory } from 'history';

import NotFound from './Components/Error/NotFound';
import Main from './Components/Main';
import Todos from './Components/Todos';
import TodosSummary from './Components/Todos/Summary';

const appHistory = useRouterHistory(createHashHistory)({ queryKey: false });

render((
  <Router history={appHistory}>
    <Route path="Todos">
      <IndexRoute name="Todos" component={Todos} />
      <Route name="TodosSummary" path="summary" component={TodosSummary} />
    </Route>
    <Route name="Main" path="/" component={Main} />
    <Route name="NotFound" path="*" component={NotFound} />
  </Router>
), document.getElementById('app'));
  • 呼び出すjsxクラスを切り替え、ルーティングのような事ができる。
    • 上記の場合はハッシュURLでのルーティングになる。(http://example.com/#/todos/summary/
    • ハッシュを利用しないこともできる。(http://example.com/todos/summary/
      • appHistory → browserHistory に置き換える。
      • 当然、アプリケーション・サーバー等でルーティングをindexに向ける等の作業が必要。

利用した書籍

入門 React ―コンポーネントベースのWebフロントエンド開発

入門 React ―コンポーネントベースのWebフロントエンド開発

ここまでで感じているReact私見(長短)

  • 良いと思ったところ
    • 仮想DOMの安心感
    • Viewに特化したわかりやすい処理系統
    • JSXでテンプレートエンジン不要
    • Flux、Redux、React Routerなどと柔軟に連携
  • 問題を感じているところ
    • デザイナーとの連携(テンプレートとロジックが近すぎるため)
    • 連携が柔軟である上でのModel、Controllerの選定リスク(Redux衰退したらどうしようとか)
    • テンプレートを内包していて容量的に重い

ひとまず締めくくります

わたしも絶賛勉強中ではありますが、上記の工程を積んでReactjsが使えるようになってきました。 次はReduxの導入・実装をおこなっていこうと思っています。