LoginSignup
10
9

More than 5 years have passed since last update.

初めてのReact.js

Last updated at Posted at 2016-08-19

React.jsでHelloWorld〜フォームの送信まで

React.jsでHello Worldを表示させる

<!-- index.html -->
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>React.js 初めの1歩</title>

    <!-- 下記のJSを使えばReact.jsの環境は作れるので入れる -->
    <script src="https://npmcdn.com/react@15.3.0/dist/react.js"></script>
    <script src="https://npmcdn.com/react-dom@15.3.0/dist/react-dom.js"></script>
    <script src="https://npmcdn.com/babel-core@5.8.38/browser.min.js"></script>
    <!-- 今回は使わない --> 
    <script src="https://npmcdn.com/jquery@3.1.0/dist/jquery.min.js"></script>
    <script src="https://npmcdn.com/remarkable@1.6.2/dist/remarkable.min.js"></script>  
  </head>
  <body>
    //React.jsで生成するHTML要素を挿入する場所
    <div id="content"></div>

    //JSタグの中に書いていく.
    <script type="text/babel">

      // Reactにおけるコンポーネントの作成(オブジェクト)
      var SampleBox = React.createClass({
        render: function() {
          return (
            <div className="sampleBox">
              <h1>初めてのReact.js</h1>
              <div>Hello, World!</div>
            </div>
          );
        }
      });

      //ReactDOM.render()
      //第一引数..renderメソッドをもったコンポーネント(オブジェクト)を渡す
      //第二引数..renderする位置を指定する
      ReactDOM.render(
        <SampleBox />,
        document.getElementById('content')
      );
    </script>
  </body>
</html>

*複数のComponentを渡すことができないため、最終的に1つにまとめる必要がある。

NG例

  <body>
    <div id="content"></div>

    <script type="text/babel">      
      var SampleBox = React.createClass({
        render: function() {
          return (
            //一番上の親要素が1つではないのでNG! :disappointed_relieved: 
            **<h1>初めてのReact.js</h1>**     
            **<div>Hello, World!</div>**
          );
        }
      });
      ReactDOM.render(
        <SampleBox />,
        document.getElementById('content')
      );
    </script>
  </body>

動的に親要素内に子要素を追加する

  <body>
    <div id="content"></div>
    <script type="text/babel">
      var ParentBox = React.createClass({
        render: function() {
          return (
            <div className="firstBox">
              <h1>初めてのReact.js</h1>
              <ChildBox />                       //ChildBoxのRenderメソッドの中身を呼び出し
            </div>
          );
        }
      });

           //子要素の作成
      var ChildBox = React.createClass({
        render: function() {
          return (
            <ul className="secondBox">
              <li>初めてのReact.js</li>
              <li>Hello, World!</li>
            </ul>
          );
        }
      });

      ReactDOM.render(
        <ParentBox />,
        document.getElementById('content')
      );

    </script>
  </body>

パラメーターのセットと表示(prop)

  <body>
    <div id="content"></div>
    <script type="text/babel">

      var ParentBox = React.createClass({
        render: function() {
          return (
            <div className="firstBox">
              <h1>初めてのReact.js</h1>
              //パラメーターを用意
              <ChildBox num="1" title="初めてのReact.js" word="Hello, World!"></ChildBox>
              <ChildBox num="2" title="2回目のReact.js" word="Hello, World2!"></ChildBox>
            </div>
          );
        }
      });

      var ChildBox = React.createClass({
        render: function() {
          return (
            <div className="secondBox">
              //取得したパラメーターを表示
              <p>要素{this.props.num}</p>
              <ul>
                <li>{this.props.title}</li>
                <li>{this.props.word}</li>
              </ul>
            </div>
          );
        }
      });

      ReactDOM.render(
        <ParentBox />,
        document.getElementById('content')
      );

    </script>
</body>

可変なパラメーターと不可変なパラメーターの扱い方(propとstate)

  <body>
    <div id="content"></div>

    <script type="text/babel">

      var ParentBox = React.createClass({
        //stateの初期化
        getInitialState() {
          return {
            articles: [
              {"num": 1, "title": "初めてのReact.js", "word": "Hello, World!"},
              {"num": 2, "title": "2回目のReact.js", "word": "Hello, World2!"}
            ]
          }
        },
        render: function() 
                    // articlesというstateの中身を受け取って、展開する
          // DOMに反映する時にこの値が参照され、最小限の変更にするために行う
          // ちなみにDev環境でkeyを指定しないとコンソールにエラーがでる
                    var articles = this.state.articles.map((article) => {
            return <ChildBox num={article.num} key={article.num} title={article.title} word={article.word}/>
          });
          return (
            <div className="firstBox">
              <h1>初めてのReact.js</h1>
              {articles}
            </div>
          );
        }
      });

      var ChildBox = React.createClass({
        render: function() {
          return (
            <div className="secondBox">
              <p>要素{this.props.num}</p>
              <ul>
                <li>{this.props.title}</li>
                <li>{this.props.word}</li>
              </ul>
            </div>
          );
        }
      });

      ReactDOM.render(
        <ParentBox />,
        document.getElementById('content')
      );

    </script>
  </body>

jsonファイルからデータを取り出し表示する

<body>
    <div id="content"></div>

    <script type="text/babel">
      var ParentBox = React.createClass({
        // JsonファイルをAjaxでリクエストを送り、Jsonの中身をstateに入れる
        //  ReactDOM.renderで、リクエストの送り先をPROP
        getJson: function() {
          $.ajax({
            url: this.props.url,
            dataType: 'json',
            cache: false,
            success: function(articles) {
              this.setState({articles: articles});
            }.bind(this),
            error: function(xhr, status, err) {
              console.error(this.props.url, status, err.toString());
            }.bind(this)
          });
        },
        getInitialState() {
          return {
            articles: []
          }
        },
        componentDidMount: function() {
          //getJsonを呼び出す
          this.getJson();
          // 2秒ごとにgetJsonを動かす設定
          setInterval(this.getJson, this.props.pollInterval);
        },
        render: function() {
          var articles = this.state.articles.map((article) => {
            return <ChildBox num={article.num} key={article.num} title={article.title} word={article.word}/>
          });
          return (
            <div className="firstBox">
              <h1>React.js 初めの1歩</h1>
              {articles}
            </div>
          );
        }
      });

      var ChildBox = React.createClass({
        render: function() {
          return (
            <div className="secondBox">
              <h2>{this.props.title}</h2>
              <p>要素{this.props.num}</p>
              <p>{this.props.word}</p>
            </div>
          );
        }
      });
      //propにリクエストURLとIntervalの時間を設定
      ReactDOM.render(
        <ParentBox url="sample.json" pollInterval={2000} />,
        document.getElementById('content')
      );

    </script>
  </body>

フォームで投稿した値をstateに入れて保持する

  <body>
    <div id="content"></div>
    <script type="text/babel">
      var ParentBox = React.createClass({
        //ParentBoxで生成したURLのpropにJson取得リクエストを送る
        getJson: function() {
          $.ajax({
            url: this.props.url,
            dataType: 'json',
            cache: false,
            success: function(articles) {
              // 取得した内容をstateにぶちこむbutikomu
              this.setState({articles: articles});
            }.bind(this),
            error: function(xhr, status, err) {
              console.error(this.props.url, status, err.toString());
            }.bind(this)
          });
        },
        // フォームで送信された内容を state articles に追加し、state articles を再構築
        handleArticleSubmit: function(article) {
          //現在の state articlesを取得
          var articles = this.state.articles;
          // 適当にid と numを追加 
          article.id = Date.now();
          article.num = Date.now();

          // フォームで送信された値を 追加
          var newArticles = articles.concat([article]);
          // state に再追加
          this.setState({articles: newArticles});
          // TODO DBに入れる場合、ここにPOSTのリクエストを書く
        },
        getInitialState() {
          return {
            articles: []
          }
        },
        componentDidMount: function() {
          this.getJson();
          // Jsonファイルを見に行き、フォームで送信した値が消えるためコメントアウト
          //setInterval(this.getJson, this.props.pollInterval);
        },
        render: function() {
          var articles = this.state.articles.map((article) => {
            return <ChildBox num={article.num} key={article.num} title={article.title} word={article.word}/>
          });
          return (
            <div className="firstBox">
              <h1>React.js 初めの1歩</h1>
              {articles}
              <ArticleForm onArticleSubmit={this.handleArticleSubmit}/>
            </div>
          );
        }
      });

      var ChildBox = React.createClass({
        render: function() {
          return (
            <div className="secondBox">
              <h2>{this.props.title}</h2>
              <p>要素{this.props.num}</p>
              <p>{this.props.word}</p>
            </div>
          );
        }
      });

      var ArticleForm = React.createClass({
        getInitialState: function() {
          return {title: '', word: ''};
        },
        handleTitleChange: function(e) {
          this.setState({title: e.target.value});
        },
        handleWordChange: function(e) {
          this.setState({word: e.target.value});
        },
        handleSubmit: function(e) {

          // 入れないとページのリロードが走る
          e.preventDefault();

          // 空白を消す
          var title = this.state.title.trim();
          var word = this.state.word.trim();

          // バリデーションはここで行う
          if (!word || !title) {
            return;
          }
          this.props.onArticleSubmit({title: title, word: word});
          // テキストフィールドに保持していた stateを消す
          this.setState({title: '', word: ''});
        },
        render: function() {
          return (
            <form className="articleForm" onSubmit={this.handleSubmit}>
              <input type="text" placeholder="タイトル" value={this.state.title} onChange={this.handleTitleChange}/>
              <input type="text" placeholder="本文" value={this.state.word} onChange={this.handleWordChange}/>
              <input type="submit" value="Post" />
            </form>
          );
        }
      });     

      ReactDOM.render(
        <ParentBox url="sample.json" pollInterval={2000} />,
        document.getElementById('content')
      );

    </script>
  </body>

参考記事

React チュートリアル
https://facebook.github.io/react/docs/tutorial-ja-JP.html

React.jsのProp
http://qiita.com/koba04/items/bc13d1f42964278ae14e

React.js + CSS
http://qiita.com/koba04/items/0e81a04262e1158dbbe4

React.jsのComponent Lifecycle
http://qiita.com/koba04/items/66e9c5be8f2e31f28461

10
9
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
10
9