Rails
React

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

More than 1 year has passed since last update.

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を返すようにすればモーダルの実装が簡単になると思います。