React使ってSPAを作るよ(10)

React使ってSPAを作るよ(10)

React使ってSPAを作るよ目次

React使ってSPAを作るよ(9)の続きです。

ヘッダにフォームを追加する

まずはモックを修正します。

See the Pen EKVLMM by natsumi (@mayo31) on CodePen.18228

幅が狭いと見づらいと思うので、できればこのモックはPCで新規タブで表示していただいた方がいいかと思います!

共有したいURLを入力する欄と、送信ボタン。
さらに、URL入力欄をクリックしたときにタグの選択エリアが表示されます。
すでに登録してあるタグをチェックボックスのリストで表示。
それから、新しく追加したいタグをinputに入力するとそのタグのチェックボックスのDOMが追加されていく想定です。

実際には送信したときに既存のタグと重複していないか判定したりこまごま処理しないといけないんですが、とりあえず見た目を作ることだけ考えます。

Reactのコンポーネントを追加する

さて、前回せっかくコンポーネント別にファイルを分割したので、このフォームもどうせならヘッダにベタで書くよりも、別ファイルで管理したいですね。

既存タグのリストはJSONファイルを作っておきます。

//tag.json
[
{
"tagID": 1,
"tagName": "タグ1"
},
{
"tagID": 2,
"tagName": "タグ2"
},
{
"tagID": 3,
"tagName": "タグ3"
}
]

そして、URLForm.jsxを用意します。

var React = require('react');

//タグ追加コンポーネント
var TagInput = React.createClass({
  render: function() {
    return (
      <input type="text" placeholder="タグ追加" id="tag-input" />
    );
  }
});

//タグリストコンポーネント
var TagInputList = React.createClass({
  render: function() {
    return (
    <ul id="tag-input-list" className="check-list"></ul>
    );
  }
});

//タグ選択コンポーネント
var TagCheckList = React.createClass({
  render: function() {
    var tagID = "tag" + this.props.tagID;
    return (
    <li><input type="checkbox" name="tag-check" id={tagID} data-tag={this.props.tagID} /><label htmlFor={tagID}>{this.props.tagName}</label></li>
    );
  }
});

//タグ選択コンポーネント
var TagCheckArea = React.createClass({

  //JSONデータ取得
  getInitialState: function() {
    return {data: []};
  },
  componentDidMount: function() {
  var t = this;
    $.ajax({
      url: './data/tag.json',
      dataType: 'json'
      })
      .done(function(data) {
        t.setState({data: data});
      })
      .fail(function(xhr, status, err) {
        console.error('./data/tag.json', status, err.toString());
      });
  },

  render: function() {
    var tagCheckNodes= this.state.data.map(function(tagCheck) {
      return (
        <TagCheckList tagID={tagCheck.tagID} tagName={tagCheck.tagName} tagData={tagCheck.tagData} />
      )
    });
    return (
    <ul id="tag-check" className="check-list paragraph">
      {tagCheckNodes}
    </ul>
    )
  }
});

//URL登録コンポーネント
var URLForm = React.createClass({
  render: function() {
    return (
    <form id="form-url-input" className="wrap">
      <input type="url" placeholder="URL" id="url-input" /><input type="submit" />
      <div id="tag-input-area" className="box">
        <TagInputList />
        <TagInput />
        <TagCheckArea />
      </div>
    </form>
    );
  }
});

module.exports = URLForm;

これまでにやってきたのと同じですね!

2016/03/07追記
#tag-inputがulの中に入っていておかしかったのでソースを少し修正しました。

そして、ヘッダに追加するためには、前回作ったSiteHeader.jsxを修正します。

var React = require('react');
var URLForm = require('./URLForm.jsx');

//サイトヘッダコンポーネント
var SiteHeader = React.createClass({
  render: function() {
    return (
      <header id="common-header">
        <h1>ヘッダh1</h1>
        <URLForm />
      </header>
    );
  }
});

module.exports = SiteHeader;

app.jsxでヘッダコンポーネントを読み込むのと同じように、フォームのコンポーネントを読み込むだけです。
こうやって分割したJSXファイルを入れ子みたいにして読み込んでいけるんですね~
( ゚д゚)ウム

最終的にできあがるソースがこれですね。

あーもう…
#bodyと#containerのネストがいや~(つд⊂)エーン
なんかいい方法ないか調べよう…

新規タグを追加する部分は、正直jQueryで書いたら早いんですが、ここらへんでそろそろReactだったらどうやるのか?を勉強したいので、ユーザの入力操作に合わせてレンダリングしていくやり方を調べたいと思います!

React使ってSPAを作るよ目次