Reactでプロフィールページ作りました

Reactを使ってプロフィールページを作ってみました。

完成品はここ

ソースはhttps://github.com/itamaev2/react-profileにあります。

使ったもの

  • create-react-app
  • material-ui

create-react-app

@chibicodeさんの記事を参考にしました。初めはreact-tutorialをベースに書いていたのですが、ES6化するのがメンドイ。。。

create-react-app使えば webpack,babel,ESLint等一発で設定させるので楽でした。

material-ui

http://www.material-ui.com/

見た目をいい感じにするために使いました。

、、、が結局いい感じにならなかった(╹◡╹)

振り返り

material-uiに時間を掛け過ぎた。

本来の目的はReactの知識を身につけることだったのですが、結果的に全体の9割の時間をmaterial-uiにかけていた。 もっと目的を意識して目的にそぐわない物は容赦なく切り捨てれば良かった。

ハマったこと

色々ハマることはありましたがその中でも一番時間をさかれたものを紹介します。

※ただの凡ミスです。

ある時画面が描画されなくなってコンソールに以下が際限なく出力され続けることがありました。

Warning: setState(...): Cannot update during an existing state transition (such as within `render` or another component's constructor). Render methods should be a pure function of props and state; constructor side-effects are an anti-pattern, but can be moved to `componentWillMount`.

原因

renderの中でsetStateを呼んでいたこと

App.js

  : 
  handleOnContentsChange(stat) {
    this.setState({content: stat});
  }

  render() {
    return (
      <MuiThemeProvider>
        <div className="App">
          <Header onContentsChange={this.handleOnContentsChange} />
          <Contents content={this.state.content} />
        </div>
      </MuiThemeProvider>
    );
  }

Header.js

  :
render() {
  return (
    <div className="header">
      <FlatButton 
         label="About me"
         onClick={this.props.onContentsChange(ContentStat.AboutMe)} />// ★ここが悪い
      <FlatButton 
         label="Contact"
         onClick={this.props.onContentsChange(ContentStat.Contact)} />// ★ここが悪い
    </div>
  );
}

上記onClickのところでAppのonContentsChangeを渡したつもりになっていたが、 この記述だとここで実行されてしまいます。。

render時にstateが更新される=>stateが更新されるとrenderが実行される=>render時にstateが更新される=>stateが・・・・ということになり無限にrenderが実行されてしまっていた。

対処方法

以下のように修正して問題解決

Header.js(修正後)

  :
render() {
  return (
    <div className="header">
      <FlatButton
        label="About me"
        onClick={ () => this.props.onContentsChange(ContentStat.AboutMe) } />
      <FlatButton
        label="Contact"
        onClick={ () => this.props.onContentsChange(ContentStat.Contact) } />
    </div>
  );
}

皆さんもお気を付けくださいね。

React始めました

突然ですがReact始めました。

今回はReactを書いて動かせるまでの手順です。
鉄板のチュートリアルを見てやったのですが、 僕の理解力が低すぎて行間が読めないところがあったので、 サクッとReactを書けるところまでを備忘録として残しておきます。

環境

  • 実行環境: OSX 10.11.6
  • Reactバージョン: v15

大まかな手順

  1. index.htmlの編集
  2. serverの起動
  3. ゴリゴリ書いていく

1. index.htmlの編集

ここからzipをダウンロードします。

でその中のpublic/index.htmlを開いて次のように変更します。

変更内容

    <script type="text/babel" src="scripts/example.js"></script> 
    <script type="text/babel">
      // To get started with this tutorial running your own code, simply remove
      // the script tag loading scripts/example.js and start writing code here.
    </script>

↓↓↓↓↓

    <script type="text/babel" src="scripts/tutorial.js"></script> 

変更後のindex.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>React Tutorial</title>
    <!-- Not present in the tutorial. Just for basic styling. -->
    <link rel="stylesheet" href="css/base.css" />
    <script src="https://unpkg.com/react@15.3.0/dist/react.js"></script>
    <script src="https://unpkg.com/react-dom@15.3.0/dist/react-dom.js"></script>
    <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
    <script src="https://unpkg.com/jquery@3.1.0/dist/jquery.min.js"></script>
    <script src="https://unpkg.com/remarkable@1.6.2/dist/remarkable.min.js"></script>
  </head>
  <body>
    <div id="content"></div>
    <script type="text/babel" src="scripts/tutorial.js"></script> 
  </body>
</html>

2. serverの起動

1.でダウンロードしてきたzipには簡単なWebサーバが含まれているので ターミナルからzipを展開したディレクトリに行って

ruby ./server.rb

で起動する。

3. ゴリゴリ書いていく

あとはpublic/scripts/tutorail.jsを作り、ここにゴリゴリ書いて

http://localhost:3000にアクセスすればOK!

grep -x って知ってましたか?

ユースケース

はじめに言っておくと かなりニッチなユースケースです。笑

アクセスログから特定のURLにアクセスしたユーザの中で リスト(user_list)にあるユーザのアクセス回数を調べる。

grep -x の使いどころ

※前提条件としてアクセスログの12カラム目にユーザIDが出力されていることとする。

今までは

cat access.log | grep ${特定のURL} | awk '{print $12}' | grep -f user_list | sort | uniq -c

こんな感じでやってたのですが、かなり時間がかかります。。

で、最近知ったgrep x オプション

cat access.log | grep ${特定のURL} | awk '{print $12}' | grep -x -f user_list | sort | uniq -c

あらビックリ!同じ結果なのに実行時間が10分の1以下に!! (アクセスログのサイズにもよると思います)

解説

manの解説では

-x, --line-regexp

パターンが行全体とぴったりマッチしたときにのみ、その行を選択します。 (-x オプションは POSIX で規定されています)

とのこと。

要するに完全一致のみを抽出するので一致しない時の判定が速く済み、結果処理が速くなるということらしいです。

皆さんも是非お試しあれ。