2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

React + ExpressでExpressにレンダリングをまかせてみたらドハマりした件

Last updated at Posted at 2018-06-05

はじめに

技術的なことはあまりないです。
ご了承を。

経緯

モダ~ンと噂の React + Express の使い方を軽くでも知っておこうと思い、
手を出しました。
express-react-viewsなるものがあり、これを使えばサクッとReact+Expressができるぞ!と意気込んでいました。
そしてコケた次第です。

結論

Expressにレンダリングをまかせると、React側でクリックイベントとかとか拾えなくなります。
気が付けず辛かった。。。

やったこと

まずはパッケージのインストールから。

yarn add babel babel-cli babel-core babel-register babel-preset-env babel-preset-react babel-plugin-runtime babel-polyfill babel-plugin-module-alias eslint express express-react-views nodemon path react

babel-registerでESの記述ができるようにします。

root/index.js
require('babel-register')();
require('./server');

つぎにローカルホストを立てるためものを。

root/server.js
import express from 'express';

const app = express();

app.listen(3000);

scriptsを追記します。

package.json
...
"scripts": {
  "dev": "nodemon ./index.js"
}
...

yarn dev

ブラウザでlocalhost:3000 にアクセスすると、Cannot GET / が表示。

次にもろもろの設定をする。

root/server.js
import express from 'express';
import expressReactViews from 'express-react-views';
import path from 'path';
import routes from './routes';

const app = express();

app.set('views', path.join(__dirname, './src/components'));
app.engine('jsx', expressReactViews.createEngine());
app.set('view engine', 'jsx');

app.use(express.static(path.join(__dirname, './src/assets')))
app.use('/', routes);

app.listen(3000);
root/routes/index.js
import express from 'express';
const router = express.Router();

router.get('/', (req, res, next) => {
  res.render('./src/components/pages/App');
});

これで下準備は大丈夫なはず。

Reactの記述はcreate-react-appを参考にちまちまと書きました。

App.jsx
import React, { Component } from 'react';

export default class App extends Component {
  render() {
    return (
      <html lang='ja'>
        <head>
          <meta charSet="UTF-8" />
          <meta httpEquiv="X-UA-Compatible" content="ie=edge" />
          <meta name="viewport" content="width=device-width, initial-scale=1.0" />
          <title>react-express-sample</title>
          <link rel="stylesheet" href="/css/reset.css" />
        </head>
        <body>
          <div>Hello React!</div>
        </body>
      </html>
    )
  }
};

(まさかメタタグとかが書けるとは思わなかった...)

無事にレンダリングができているようでなにより。
そしてAPIの実装に入る前に、動作確認をしようと思った。
ここで盛大に事故る。

App.jsx
export default class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      value: 0
    };
  }

  onClick() {
    this.setState({ value: this.state.value += 1 });
  }

...
        <body>
          <div>{ this.state.value }</div>
          <div onClick={ this.onClick }>click</div>
        </body>
...

これでぽちぽちすると数字が増えていくはず!

ぽちぽち
......ぽちぽちぽち
...ぽちぽちぽちぽちぽちぽちぽちぽちp

ふへぁ...っ!!

悲しきことに無反応である。
タイポや設定し忘れ、console.logを張ったり、バインドの記述を追記してみたり、設定ミスを探すも(ディレクトリ構成は触れない方向)致命傷はないよう。。。

もんもんとしながら検索をかけてみた。
同じことをやってるやってる。

express-react-viewsなんていうからReactとにたことができる!
と勘違いしてしまった我の救いようのなさよ。

仕方がない。できないものは仕方がない。
react-domとreact-routerでレンダリングとかとかしよう。そうしよう。

まとめ

React + ExpressでExpressにレンダリングは丸投げできない。
このひとことに尽きます。

その他

日本語不自由なため、読みにくい文章だったとおもいますが、
最後まで付き合っていただき、ありがとうございます。

ExpressでMySQLに接続できることを知った今日この頃。

2
1
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
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?