LoginSignup
8
8

More than 5 years have passed since last update.

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

Posted at

reactとポップアップ

ポップアップのモジュール:react-popout

install

npm install --save react-popout

ポップアップのサンプル

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

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;


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(再描画)のサンプル

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;

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;


8
8
1

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
8
8