LoginSignup
8
12

More than 5 years have passed since last update.

react-railsでモーダルを実装する

Last updated at Posted at 2016-12-08

react-railsでのモーダルの実装の方法をまとめます。
npmでReactのモーダル系ライブラリをインストールすればさくっと実装できるのですが、今回npmが使えないRails環境だったので、Gemを使った方法と自前実装する方法について見ていきます。

Gemを使って簡単に実装する場合

react_rails_modalを使います。

インストール

まずreact-railsとreact_rails_modalをGemfileに追加します。

Gemfile
gem 'react-rails'
gem 'react_rails_modal'

インストールします。

$ bundle install

インストールコマンドを実行します。

$ rails g react:install
$ rails g react_rails_modal:install

これによりapplication.jsに下記が追記されます。

app/assets/javascripts/application.js
//= require react
//= require react_ujs
//= require components
//= require react_rails_modal

これでマニフェストファイルにライブラリの読み込みが宣言されました。

初期設定

続いて、react-railsの環境変数を設定します。

# config/environments/development.rb
MyApp::Application.configure do
  config.react.variant = :development
end

# config/environments/production.rb
MyApp::Application.configure do
  config.react.variant = :production
end

使い方

jsxファイルの中でModalComponentコンポーネントを宣言して使います。

<ModalComponent
  isOpen={bool}
  onCloseRequest={requestCloseFunction}
  style={customStyle}
>
  <h1>Modal Component Content</h1>
  <p>Text</p>
</ModalComponent>

実装例

具体的な使い方は下記のようになります。

app/controller/views/以下のテンプレートファイルで、Reactコンポーネントを呼び出します。
今回はHelloコンポーネントを呼び出しています。

<%= react_component('Hello') %>

Helloコンポーネントはjsxファイルの中で定義します。
その中でModalComponentを呼び出しており、ここがモーダル部分になります。

モーダルの開閉状態をstateで持って、クリックに応じてモーダルの開閉状態を切り替える関数を用意しています。
スタイルに関してはオーバーレイとモーダル本体それぞれを指定することができます。

class Hello extends React.Component {
  constructor(props) {
    super(props);
    this.closeModal = this.closeModal.bind(this);
    this.openModal = this.openModal.bind(this);
    this.state = { isModalOpen: false };
  }

  closeModal() {
    this.setState({ isModalOpen: false });
  }

  openModal() {
    this.setState({ isModalOpen: true });
  }

  render () {
    return (
      <div>
        <button onClick={this.openModal}>Open Modal</button>
        <ModalComponent
          isOpen={this.state.isModalOpen}
          onCloseRequest={this.closeModal}
          style={Hello.styles}
        >
          <h1>Hello world!</h1>
          <button onClick={this.closeModal}>Close</button>
        </ModalComponent>
      </div>
    );
  }
}

Hello.styles = {
  overlay: {
    backgroundColor: 'rgba(0,0,0,0.75)',
    bottom: '0',
    height: '100%',
    position: 'fixed',
    top: '0',
    left: '0',
    right: '0',
    width: '100%',
    zIndex: '1',
  },
  modal: {
    background: '#fff',
    left: '5%',
    padding: '15px 30px',
    position: 'relative',
    top: '10%',
    width: '80%',
    zIndex: '2',
  }
}

これでモーダル完成です。

自前実装する場合

ここからは自前実装する方法について見ていきます。

app/controller/views/以下のテンプレートファイルで、Reactコンポーネントを呼び出します。

<%= react_component('Hoge') %>

Hogeコンポーネントの中でModalコンポーネントを呼び出します。
親であるHogeコンポーネントで、モーダルの開閉状態のstateおよびその関数は定義します。

hoge.es6.jsx
class Hoge extends React.Component {
  constructor(props) {
    super(props);
    this.closeModal = this.closeModal.bind(this);
    this.openModal = this.openModal.bind(this);
    this.state = { isModalOpen: false };
  }

  closeModal() {
    this.setState({ isModalOpen: false });
  }

  openModal() {
    this.setState({ isModalOpen: true });
  }

  render() {
    return (
      <div>
        <button onClick={this.openModal}>Open Modal</button>
        <Modal isOpen={this.state.isModalOpen} onClose={this.closeModal} />
      </div>
    );
  }
}

Modalコンポーネントの中では、引数として渡されたthis.props.isOpenfalseの場合、nullを返しています。
これによりモーダルを非表示にできます。

modal.es6.jsx
class Modal extends React.Component {
  render() {
    if (!this.props.isOpen) {
      return null;
    }

    return (
      <div>
        <div onClick={this.props.onClose} style={Modal.styles.overlay} />
        <div style={Modal.styles.content}>
          <h1>Hello modal!</h1>
          <button onClick={this.props.onClose}>Close</button>
        </div>
      </div>
    );
  }
}

Modal.styles = {
  overlay: {
    backgroundColor: 'rgba(0,0,0,0.75)',
    bottom: '0',
    height: '100%',
    position: 'fixed',
    top: '0',
    left: '0',
    right: '0',
    width: '100%',
    zIndex: '1',
  },
  content: {
    background: '#fff',
    left: '5%',
    padding: '15px 30px',
    position: 'relative',
    top: '10%',
    width: '80%',
    zIndex: '2',
  }
}

以上でモーダルを自前実装できました。
親クラスでモーダルの開閉状態を管理することと、モーダルが閉じているときはrenderでnullを返すようにすればモーダルの実装が簡単になると思います。

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