takumiblog

新人エンジニアの技術ブログ

Reactでモーダル実装するための仕組みについて

 この記事について

モーダル実装の仕組みについて理解を深めるために、書き留めておきます。

完成コード

[Main.js]

import React from 'react';
import Lesson from './Lesson';

class Main extends React.Component {
  render() {
    const lessonList= [
      {
        name: 'HTML & CSS',
        image: 'https://s3-ap-northeast-1.amazonaws.com/progate/shared/images/lesson/react/html.svg',
        introduction: 'WEBページはHTML、CSSという言語によってその見た目が作られています。 実際にWEBページを作りながら学んでみましょう!',
      },
      {
        name: 'Sass',
        image: 'https://s3-ap-northeast-1.amazonaws.com/progate/shared/images/lesson/react/sass.svg',
        introduction: 'SassはCSSをより便利に効率的にするための言語です。',
      },
      {
        name: 'JavaScript',
        image: 'https://s3-ap-northeast-1.amazonaws.com/progate/shared/images/lesson/react/es6.svg',
        introduction: 'JavaScriptはフロントエンドだけでなく、サーバーサイドまで広い可能性を持つプログラミング言語です。',
      },
      {
        name: 'React',
        image: 'https://s3-ap-northeast-1.amazonaws.com/progate/shared/images/lesson/react/react.svg',
        introduction: 'ReactはHTMLのように、サイトの見た目をつくることができるJavaScriptのライブラリです。',
      },
    ];
    return (
      <div className='main-wrapper'>
        <div className='main'>
          <div className='copy-container'>
            <h1>Hello, World.</h1>
            <h2>プログラミングの世界へようこそ!</h2>
          </div>
          <div className='lesson-container'>
            <h3 className='section-title'>学べるレッスン</h3>
            {lessonList.map((lessonItem) => {
              return (
                < Lesson
                  name = {lessonItem.name}
                  image = {lessonItem.image}
                  introduction ={lessonItem.introduction}
                />
              )
            })}
          </div>
        </div>
      </div>
    );
  }
}

export default Main;

[Lesson.js]

import React from 'react';

class Lesson extends React.Component{
    constructor(props) {
        super(props);
        this.state={isModalOpen:false}
    }
    handleClickLesson() {
        this.setState({isModalOpen: true});
    }
    handleClickClose() {
        this.setState({isModalOpen: false});
    }
    render() {
        let modal ;
        if (this.state.isModalOpen) {
            modal = (
                <div className='modal'>
                    <div className='modal-inner'>
                        <div className='modal-header'></div>
                        <div className='modal-introduction'>
                        <h2>{this.props.name}</h2>
                        <p>{this.props.introduction}</p>
                        </div>
                        <button
                            className='modal-close-btn'
                            onClick={() => {this.handleClickClose()}}
                        >
                        とじる
                        </button>
                    </div>
                </div>
            )
        }
        return(
            <div className='lesson-card'>
                <div
                    className='lesson-item'
                    onClick={() => {this.handleClickLesson()}}
                >
                    <p>{this.props.name}</p>
                    <img src={this.props.image} />
                </div>
            {modal}
            </div>

        );
    }
}
export default Lesson;

モーダル実装の流れ

1モーダルの画面を作成

2通常は非表示に設定する

3クリックイベントでモーダルを表示or非表示

1モーダルの画面を作成

該当コード

<div className='modal'>
    <div className='modal-inner'>
     <div className='modal-header'></div>
     <div className='modal-introduction'>
      <h2>{this.props.name}</h2>
       <p>{this.props.introduction}</p>
     </div>
     <button
      className='modal-close-btn'
       onClick={() => {this.handleClickClose()}}
      >
       とじる
    </button>
    </div>
</div>

this.props.nameで表示の切り替えを行うことができる。

2通常は非表示に設定する

該当コード

constructor(props) {
        super(props);
        this.state={isModalOpen:false}
 }

isModalOpenメソッドを通常falseとしている。

こうすることでモーダルの表示を通常非表示にすることができ、if文を用いてtrueを返すことで表示するコードが書けるようになる。

3クリックイベントでモーダルを表示or非表示

該当コード

    handleClickLesson() {
        this.setState({isModalOpen: true});
    }
    handleClickClose() {
        this.setState({isModalOpen: false});
    }

 let modal ;
        if (this.state.isModalOpen) {
            modal = (
                <div className='modal'>
                    <div className='modal-inner'>
                        <div className='modal-header'></div>
                        <div className='modal-introduction'>
                        <h2>{this.props.name}</h2>
                        <p>{this.props.introduction}</p>
                        </div>
                        <button
                            className='modal-close-btn'
                            onClick={() => {this.handleClickClose()}}
                        >
                        とじる
                        </button>
                    </div>
                </div>
            )
        }
        return(
            <div className='lesson-card'>
                <div
                    className='lesson-item'
                    onClick={() => {this.handleClickLesson()}}
                >
                    <p>{this.props.name}</p>
                    <img src={this.props.image} />
                </div>
            {modal}
            </div>

        );

handleClickLessonhandleClickCloseメソッドを定義することで、クリック後の表示・非表示処理を実装できるようになる。

let modal空の変数を定義することで、真偽値を返した時に処理を変えることが出来る。

if (this.state.isModalOpen)openがtrueということ。つまりモーダルが表示されていることになるので、直下にモーダルの記述を持ってくる。

onClick={() => {this.handleClickClose()}}とすることで、クリックイベントを実行し、handieClickCloseメソッドを呼び出す(非表示する)

onClick={() => {this.handleClickLesson()}}は、先ほどの逆で表示するメソッドをクリックイベントで呼び出す。

参考記事

https://prog-8.com/dashboard