ページ

ラベル React の投稿を表示しています。 すべての投稿を表示
ラベル React の投稿を表示しています。 すべての投稿を表示

2017年12月10日日曜日

改めてReactをやってみる1

少し前にReactやったが、時間が過ぎたので改めてやってみる。

React

:computer:環境構築


Create React App というものが用意されているらしい。
折角なのでそれを使って環境を構築してみる。
sh
$ npm install -g create-react-app
$ create-react-app react-sample
Editor
こちらにおすすめパッケージやらが乗っている
とりあえずAtom使いなのでlanguage-babelはインストール

:pencil: 実装


簡単なサンプル

チュートリアルにもあるように一旦src/*のファイルを削除
index.cssindex.jsを追加し、index.jsを以下のように修正
js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
yarn startすると空のページが表示される。

コンポーネントを作る

チュートリアルにあるサンプルのコンポーネントを試してみる
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';

class ShoppingList extends React.Component {
  render() {
    return (
      <div className="shopping-list">
        <h1>Shopping List for {this.props.name}</h1>
        <ul>
          <li>Instagram</li>
          <li>WhatsApp</li>
          <li>Oculus</li>
        </ul>
      </div>
    );
  }
}

ReactDOM.render(<ShoppingList name="Mark" />, document.getElementById('root'));
実行結果
image.png (15.3 kB)

:bomb: バッドノウハウ


create-react-appでエラー
error An unexpected error occurred: "https://registry.yarnpkg.com/setimmediate: socket hang up".
info If you think this is a bug, please open a bug report with the information provided in "/Users/xxxxx/react-sample/yarn-error.log".
info Visit https://yarnpkg.com/en/docs/cli/add for documentation about this command.
Error: socket hang up
    at TLSSocket.onHangUp (_tls_wrap.js:1124:19)
    at TLSSocket.g (events.js:292:16)
    at emitNone (events.js:91:20)
    at TLSSocket.emit (events.js:185:7)
    at endReadableNT (_stream_readable.js:974:12)
    at _combinedTickCallback (internal/process/next_tick.js:80:11)
    at process._tickCallback (internal/process/next_tick.js:104:9)
Error: socket hang up
    at TLSSocket.onHangUp (_tls_wrap.js:1124:19)
    at TLSSocket.g (events.js:292:16)
    at emitNone (events.js:91:20)
    at TLSSocket.emit (events.js:185:7)
    at endReadableNT (_stream_readable.js:974:12)
    at _combinedTickCallback (internal/process/next_tick.js:80:11)
    at process._tickCallback (internal/process/next_tick.js:104:9)
原因: 自分の場合はウィルス対策ソフトを一時的に無効化したらすんなり通った。。

:link: 関連リンク


2016年11月6日日曜日

PhoneGapを使用する 5 - React Hot Reloading Templateを試す -


Phonegapの公式テンプレートで
react-hot-loaderがあります。(※筆者のPhonegapのバージョン:6.3.2)
$ phonegap template list
・・・省略・・・
react-hot-loader   Starter PhoneGap project using React.js, Babel, Webpack and Hot Reloading.
PhonegapでReact.jsを使えて、環境はBabel、WebpackでHot Reloadingする
という事なので早速試してみたいと思います。

プロジェクト作成


プロジェクトの作成は以下のコマンドでサクッと作成できます。
$ phonegap create [プロジェクト名] --template react-hot-loader
作成したプロジェクトの構成は次のようになっています。
.
├── config.js
├── config.xml
├── env.js
├── hooks
├── package.json
├── platforms
├── plugins
├── res
├── src
│   ├── components
│   │   ├── Hello.js
│   │   └── Message.js
│   ├── css
│   │   ├── hello.css
│   │   ├── index.css
│   │   └── message.css
│   └── index.js
├── webpack.config.js
└── www
    ├── icon.png
    └── index.html
ちゃんとwebpack.config.jsが用意されています。
.jsxが見当たらないですが、Hello.js、Message.jsで実装されてます。
次に依存パッケージをインストールします。
$ npm install
これで準備完了です。

ブラウザで実行&確認


それでは早速実行してみたいと思います。
まずはブラウザで確認。
$ npm start
起動完了後http://localhost:8080を見てみると
gif1
↑のような画面が表示されており。ボタンを押すと「Hello World」と表示され
しばらく経つと消えます。
次にHot Reloadが効いているか確認してみます。
gif2
ちょっと分かりにくいかもしれませんが、ボタンの文字を修正し
保存するとちゃんとブラウザ側のボタンに反映されています。

iOSシュミレータで確認


次はiOSのシュミレータで確認してみます。
まずはiOS用のプラットフォームを追加。
$ phonegap cordova platform add ios
次にシュミレータで動作する用にビルドしてやる必要があります。
ビルドせずに動かすと以下のエラーが発生します。
Failed to load webpage with error: Could not connect to the server.
また、Phonegapを使用している場合、package.jsonを以下のように修正します。
・・・省略・・・
"scripts": {
  "android": "phonegap cordova run android",
  "ios": "phonegap cordova run ios",
  "prepare": "node config && webpack && phonegap cordova prepare",
  "build": "node config && webpack && phonegap cordova build",
  "start": "node config && HOST=0.0.0.0 webpack-dev-server",
  "test": "echo \"No tests (yet!) -- submit a PR?\" && exit 0"
},
・・・省略・・・
あとは、
$ npm run build -- ios
$ npm run ios
で↓のようにシュミレータで動作できればOKです。
gif3

まとめ


Hot Reloadもできて、Babel, Webpackも揃っているので、
とても使いやすいのではないかと思います。
今後PhonegapでReact.jsを使う必要がある場合はオススメです。

2016年10月2日日曜日

Reactを使う 5 - ログイン画面 -


今回は簡単なログイン画面を作ってみたいと思います。
の前に・・余談ですがエディッタにatomを使っている場合、
デフォルトだと.jsxファイルを開いてもシンタックスハイライトされていません。
そこでreactパッケージをインストールすると.jsxファイルが
シンタックスハイライトされて表示されるようになります。
本当にただの余談でしたw

コンポーネント作成

構成は今まで通りで、今回はlogin.jsxを新たに作成します。
まずは画面だけを作成します。login.jsxを次のように実装します。
import React from 'react';
import ReactDOM from 'react-dom'

class Login extends React.Component {

  constructor() {
    super();
    this.state = {
      msg: 'none'
    };
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleSubmit(e) {
    console.log('handleSubmit');
  }

  render() {
    return (
      <div className="login">
        <h1>Login</h1>
        <form className="loing form" onSubmit={this.handleSubmit}>
          <input type="text" placeholder="Name" />
          <input type="text" placeholder="Password" />
          <input type="submit" value="Submit" />
        </form>
        <p>{this.state.msg}</p>
      </div>
    );
  }
}

ReactDOM.render(
  <Login />,
  document.getElementById('container')
);
↑でclassではなくclassNameとなっていますがclassと同じ働きをします。
また、↑ではSubmitボタンを押してもコンソールにログが出るだけになってます。
実行結果


イベント処理

次にSubmitボタンを押したら入力された名前とパスワードを
画面に表示させてみたいと思います。
まずはinputrefを追加します。
  • refとは? ・・・ inputなどの要素にアクセスできるようにするもの
                              要素へアクセスするにはReactDOM.findDOMNodeを使う
という事で早速refを追加してみます。
<form className="loing form" onSubmit={this.handleSubmit}>
  <input type="text" placeholder="Name" ref={(ref) => this.inputName = ref} />
  <input type="text" placeholder="Password" ref={(ref) => this.inputPass = ref} />
  <input type="submit" value="Submit" />
</form>
コールバックとして受け取ったrefthis.inputNamethis.inputPassに設定しています。
次にhandleSubmitを次のように修正します。
handleSubmit(e) {
  e.preventDefault(); // デバッグ用

  let name = ReactDOM.findDOMNode(this.inputName).value.trim();
  let pass = ReactDOM.findDOMNode(this.inputPass).value.trim();
  let message = `name[${name}] pass[${pass}]`;

  this.setState({msg: message});
}
本来ならSubmitボタンが押されたらサーバー側で処理してログイン後の画面に
遷移したりするのですが、今回はデモの為イベントをpreventDefaultによって
止めています。
this.inputNamethis.inputPassから値を取り出しメッセージを出力させています
実行するとinputに入力された内容が画面に表示されているかと思います。

スタイルシート適用

classNameで指定した部分にスタイルシートを適用させてみます。
と言っても普通のCSSと変わりないです。
.login {
  background: #e0ffff;
}

.form {
  background: #fff8dc;
}
背景色を変更。リロードすると以下のようになります。


2016年9月25日日曜日

Reactを使う 4 - state -


今回はstateを使ってみたいと思います。
state
propsとの違いは、値の変更が可能で
コンポーネント作成後でも値を設定できます。

サンプルとして今回はいいねボタンを作成してみたいと思います。
最終的な完成版がこちら↓
gif1
しょぼいというツッコミは無しで・・

コンポーネント作成

構成は今までと同じで以下の通りです。
.
├── index.html
├── package.json
├── src
│   ├── container.js
│   └── good_button.jsx ☆
└── webpack.config.js
今回新たにgood_button.jsxを作成します。
最終的な内容がこちら↓
import React from 'react';
import ReactDOM from 'react-dom'

class GoodButton extends React.Component {
  constructor() {
    super();
    // [1]
    this.state = {
      goods: 0
    };
    this.handleClick = this.handleClick.bind(this); // [4]
  }

  handleClick() {
    this.setState({goods: this.state.goods + 1}); // [3]
  }

  render() {
    return (
      // [2]
      <button onClick={this.handleClick}>
        +{this.state.goods}
      </button>
    );
  }
}

ReactDOM.render(
  <GoodButton />,
  document.getElementById('container')
);
GoodButtonクラスは今回goodsというstateの値を持っています。
まずコンストラクタでgoods0に初期化しています。・・・[1]
次にボタンが押されたイベントでthis.handleClickを指定しています。・・・[2]
handleClickでは現在のgoodsの値を+1しています。・・・[3]
とまあいたってシンプルです。

ちなみに・・
[4]の処理は何をしているかというと、handleClick内でthisを使ってますが
[4]の処理がないとbuttonのthisになってしまいエラーになってしまいます。
試しに[4]の処理をコメントアウトして実行するとコンソールに
以下のエラーが表示されました。


今回のはしょぼいですが、CSSをちゃんと使ってかっこいいボタンも作れると思います。