react.jsで、ポップアップと、親の再描画(更新)について

# reactとポップアップ

ポップアップのモジュール：[react-popout](https://github.com/JakeGinnivan/react-popout)

###install
`npm install --save react-popout`

###ポップアップのサンプル

親画面に、記事を新規登録するリンクがあるだけ。
押すと、ポップアップが表示されて、[新規登録]と[閉じる]ボタンがある子画面がポップアップで表示される。

```js:input.js

/*
記事を登録するポップアップのモジュール
*/
import React from 'react';
import Popout from 'react-popout';
import request from 'superagent';

class Input extends React.Component {
  constructor(props) {
    super(props);
    this.popout = this.popout.bind(this);
    this.popoutClosed = this.popoutClosed.bind(this);
    this.popoutContentClicked = this.popoutContentClicked.bind(this);
    this.state = { isPoppedOut: false };
  }

  handleSubmit(e) {
    e.preventDefault();
    let contents = this.refs.contents.value;
    /*
    登録処理
    */
    this.setState({isPoppedOut: false});
  }

  popout() {
    this.setState({isPoppedOut: true});
  }

  popoutClosed() {
      this.setState({isPoppedOut: false});
  }

  popoutContentClicked() {
    this.popoutClosed();
  }

  render() {
    return (
      <div>
        { this.state.isPoppedOut ?
          <Popout title='Test' onClosing={this.popoutClosed}>
            <div>
              <h3>記事入力</h3>
              <form onSubmit={this.handleSubmit.bind(this)}>
                <table>
                  <tbody>
                  <tr>
                    <td>
                      <label>記事詳細</label>
                    </td>
                    <td>
                      <textarea ref="contents" type="text" placeholder="" required/>
                    </td>
                  </tr>
                  </tbody>
                </table>
                <div>
                  <input type="submit" value="登録" />
                </div>
              </form>
              <div onClick={this.popoutContentClicked}>閉じる</div>
            </div>
          </Popout> : false }
        <div>
          <!-- これは親画面に表示される -->
          <a onClick={this.popout}><u>新規登録</u></a>
        </div>
      </div>
    );
  }
}
export default Input;


```

```js:NewsListPage.js
import React, { Component } from 'react';
import { render } from 'react-dom';
import Input from './Input';

class NewsListPage extends Component {
  constructor(props) {
    super(props);
    this.state = {};
  }
  render() {
    return (
      <div>
        <h1>記事管理</h1>　
        <Input />
      </div>
    );
  }
}

export default NewsListPage;

```

###子Componentから、親Componentのreload(再描画)のサンプル


```js:NewsListPage.js
import React, { Component } from 'react';
import { render } from 'react-dom';
import Input from './Input';

class NewsListPage extends Component {
  constructor(props) {
    super(props);
    this.state = {};
  }
  loadNewsFromServer(id) {
  /* apiから記事情報を読み込む処理 */
  }

  componentWillMount() {
    this.loadNewsFromServer();
  }

  componentWillReceiveProps() {
    this.loadNewsFromServer();
  }

  /* 子Componentに渡す用のメソッド */
  _reloadNews(){
    this.loadNewsFromServer();
  }

  render() {
    return (
      <div>
        <h1>記事管理</h1>
        <!-- 子componentにreloadNewsとして渡す。--//>
        <Input reloadNews={this._reloadNews.bind(this)}/>
        <!-- ここで登録情報を描画するコンポーネントが必要(今回は割愛) --//>
      </div>
    );
  }
}

export default NewsListPage;

```


```js:input.js

/*
記事を登録するポップアップのモジュール
*/
import React from 'react';
import Popout from 'react-popout';
import request from 'superagent';

class Input extends React.Component {
  constructor(props) {
    super(props);
    this.popout = this.popout.bind(this);
    this.popoutClosed = this.popoutClosed.bind(this);
    this.popoutContentClicked = this.popoutContentClicked.bind(this);
    this.state = { isPoppedOut: false };
  }

  handleSubmit(e) {
    e.preventDefault();
    let contents = this.refs.contents.value;
    /*
    登録処理
    */
    /* ここで、親から渡されたreloadを実行 */
    this.props.reloadNews();
    this.setState({isPoppedOut: false});
  }

  popout() {
    this.setState({isPoppedOut: true});
  }

  popoutClosed() {
      this.setState({isPoppedOut: false});
  }

  popoutContentClicked() {
    this.popoutClosed();
  }

  render() {
    return (
      <div>
        { this.state.isPoppedOut ?
          <Popout title='Test' onClosing={this.popoutClosed}>
            <div>
              <h3>記事入力</h3>
              <form onSubmit={this.handleSubmit.bind(this)}>
                <table>
                  <tbody>
                  <tr>
                    <td>
                      <label>記事詳細</label>
                    </td>
                    <td>
                      <textarea ref="contents" type="text" placeholder="" required/>
                    </td>
                  </tr>
                  </tbody>
                </table>
                <div>
                  <input type="submit" value="登録" />
                </div>
              </form>
              <div onClick={this.popoutContentClicked}>閉じる</div>
            </div>
          </Popout> : false }
        <div>
          <!-- これは親画面に表示される -->
          <a onClick={this.popout}><u>新規登録</u></a>
        </div>
      </div>
    );
  }
}
export default Input;


```