LoginSignup
3
1

More than 5 years have passed since last update.

create-react-appで作成したReact+Material-UI開発環境のメモ

Last updated at Posted at 2017-09-21

概要

create-react-appで作成したReact+Material-UI開発環境、を昨日から使い始めました!いろいろ詰まると思うので、それぞれメモっておきたいとおもいます。

とりあえず公開しておきますが、今後も随時追加していく予定です。

開発環境のつくりかた

まずは以下の2つのツールを使えるようにしておいて

npm install -g create-react-app
npm install -g serve

例えば react-test という開発環境を作成するとすると、以下を順に実行します。

create-react-app react-test
cd react-test
npm install material-ui --save
npm start

これでブラウザが起動してサンプルページが表示されますので、あとは src/App.js を修正するだけ!

完成したら以下を実行してブラウザで表示を確認し、問題なければ build フォルダをWebサーバーなどにアップロード&公開して完了。

npm run build
serve -s build

詳しい経緯は React開発環境のセットアップで挫折し、create-react-appに救われた件 を参考にしてみてください。

テーマエラーが表示されてしまう

以下のように Material-UI のパーツを <MuiThemeProvider> タグで囲んでください。

<MuiThemeProvider>
  <Chip onRequestDelete = {() => alert("delete")}>
    Chip test
  </Chip>
</MuiThemeProvider>

アイコンが表示されない

JSX で以下のようにタブなどにアイコンを設定しても

  <Tabs>
  <Tab
    icon={<FontIcon className="material-icons">home</FontIcon>}
    label="HOME"
  >

以下のようにアイコンではなく文字で表示されてしまう場合、

image.png

Google が提供しているフォントアイコン用の以下のCSSが読み込まれていないのが原因のようです。なのでこのファイルをローカルに保存し、

<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">

以下のように import してあげればokです。

import './MaterialIcons.css';

image.png

なおアイコンを探す場合は Material icons - Material Design からどうぞ。

リストの値を覚えてくれない

値をひとつ選択できる SelectField ですが、最初、以下のように簡単に書いたら値を覚えてくれませんでした。選択しても空のままです。

<SelectField floatingLabelText="List selection">
  <MenuItem value={1} primaryText="categoiry1" />
  <MenuItem value={2} primaryText="categoiry2" />
  <MenuItem value={3} primaryText="categoiry3" />
</SelectField>

状態を覚えさせるためには、公式サイトのサンプルのように、クラス化する必要がありそうです。でも数多くある場合、いちいちクラス化するのも面倒ですよね?

とりあえず以下のように記述したら値を覚えてくれました。

<SelectField floatingLabelText="List selection"
  value={this.state ? this.state.value : 1}
  onChange={(event, index, values) => this.setState({value:values})}
>
  <MenuItem value={1} primaryText="categoiry1" />
  <MenuItem value={2} primaryText="categoiry2" />
  <MenuItem value={3} primaryText="categoiry3" />
</SelectField>

クラス化しないと SelectField 内の state を初期化できない、なので最初に value 属性をセットする際に undefined エラーになる、のが問題のようでした。

そこでちょっと強引ですが、value 属性の式に、state が未定義の場合には初期値(今回は1)を渡すように処理を加えてみました。ちなみに onChange 式のほうは公式のクラス化するコードと同じです。

で、うまく動作するようにみえましたが… これは駄目でした。2個目の SelectField を追加すると、両者で値が連動してしまいます。つまり、state を共有してしまうようで、クラス変数になっちゃってる?感じの動きです。

なので上記のサンプルをちょっと修正した以下を利用しました。まず値を保持するために専用の変数を用意して、初期値をセットしておきます。

var sf_value1 = 1;

後は処理を以下のように書き換えればok。

<SelectField floatingLabelText="List selection"
  value={sf_value1}
  onChange={(event, index, values) => {sf_value1 = values; this.setState({value:values})}}
>

かなりベタな感じになりましたが、それぞれ別々のクラスを定義するよりはマシかと。

ただしこの方法だと、たぶん this.setState() でこの方法で実装した全てのSelectField に更新イベントが飛ぶとおもわれます。あまりに数が多かったり、リストの動的作成などで処理が重いものがあれば、ちゃんとクラス化したほうが良いとおもわれます。

こんど余裕があったら、複数あっても連動しない、簡単に使えるリスト部品が作れないか考えてみたいとおもいます。

Node.js サーバーと通信できない

自作の Node.js アプリのフロント部分を React+Material-UI で書き直してみたのですが、アプリAPIへのアクセスが動作しなくて困りました。

自身の Node.js アプリは //localhost:6001/api/* でサービスを受けつけているのですが、create-react-app でプレビュー中のページは //localhost:3000/ なので、CORS(Cross-Origin Resource Sharing) 問題が発生してアクセスできません。ビルドして Node.js アプリ側に反映すれば動作しますが、時間がかかり面倒です。

たぶん create-react-app でプレビュー用に動作しているwebサーバーのヘッダに Access-Control-Allow-Origin: を設定すれば良いのですが、いまいちどう動作しているかわからず…

とりあえず現在は Chrome Extension の CORS で無理やりアクセスを許可させて動作確認しています。こんな感じで…

image.png

おわりに

React + Material-UI を使い始めて2日ですが、開発環境さえ作ってしまえば、わりと使いやすく、かつ洗練されたUIで良いとオモイマス。既に手元のアプリを1つ、この環境に移植中…

ただReact、というか Facebookのライセンス問題 (Facebook社と特許で係争中の会社はコードを利用できない、的な)を知って、大手のプロジェクトでは利用できない可能性が高いな、とちょっと意欲が減退気味。どうしようかな…

【追記】MITライセンスになるようで、よかった!

ではまた!

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