💭

[React]Reactを使用したModal機能🧚‍♀️

2024/08/28に公開

前はBootstrap(ver4)を使用したmodal機能を実装しましたが今回はReactを使用してmodalを実装していこうと思います!!
ちなみに下記がBootstrapを使用したModal機能です🪼
https://zenn.dev/takeda_kaho/articles/e10f26391da538

Modal機能の作成手順

  • STEP1:モーダルの記載を追加
  • STEP2:初期状態でモーダルを隠す
  • STEP3:ifを使って非表示・表示を切り替える
  • STEP:4 ボタンで表示と非表示の切り替える

STEP1:モーダルの記載を追加

Main.jsの方

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

class Main extends React.Component {
render() {
const lessonList = [
{
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>学べるレッスン</h3>
        {lessonList.map((lessonItem) => {
          return (
            <Lesson
              name={lessonItem.name}
              image={lessonItem.image}
              introduction={lessonItem.introduction}
              
            />
          );
        })}
      </div>
    </div>
  </div>
);

}
}

export default Main;

まず、Reactの Lesson.js コンポーネントにモーダルのHTML構造を追加します。

Lesson.jsに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'>
      とじる
    </button>
  </div>
</div>

STEP2:初期状態でモーダルを隠す

真偽値型のstateを使用してtrue→表示 / false→falseとなるようにします。
stateはconstructorで初期化できる。今回は初期状態でモーダルを非表示にしたいので、isModalOpenというstateの初期値をfalseに設定します。

Lesson.js
constructor(props) {
  super(props);
  // stateの初期値を定義
  this.state={isModalOpen:false}
  }

これで、モーダルは初期状態で非表示になります。

STEP3: ifを使って非表示・表示を切り替える

isModalOpentrueのときだけモーダルが表示されるように実装します。

  1. modalという変数を用意
  2. 条件分岐を行いisModalOpentrueのときだけJSXが代入されるようにする。
    (render内で定義・条件分岐をしてrerurn内で{定義名}で出力する)
Lesson.js
import React from 'react';

class Lesson extends React.Component {
  constructor(props) {
    super(props);
    this.state = {isModalOpen: false};
  }

  render() {
    // ⭐️変数modalを定義
    let modal;
    
    // ⭐️if文を用意
    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'>
              とじる
            </button>
          </div>
        </div>
      )
    }
    
    return (
      <div className='lesson-card'>
        <div className='lesson-item'>
          <p>{this.props.name}</p>
          <img src={this.props.image} />
        </div>
        {modal} {/* 変数モーダルを表示 */}
      </div>
    );
  }
}
export default Lesson;

STEP:4 ボタンで表示と非表示の切り替える

handleClickLessonメソッドでModalを表示するためにisModalOpenをtrueに設定。
handleClickCloseメソッドでModalを非表示にするためにisModalOpenをfalseに設定。
これにより

  • モーダルをクリックで表示/閉じるボタンで非表示にするという基本的なモーダル機能が完成!
renderで定義
// 表示ボタン
handleClickLesson() {
  this.setState({isModalOpen: true});
}

// 非表示ボタン
handleClickClose(){
  this.setState({isModalOpen:false});
}
出力
// 表示ボタン
onClick={() => {this.handleClickLesson()}}

// 非表示(閉じる)ボタン
onClick={()=>{this.handleClickClose()}}
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>
            {/* onClickイベントを追加 */}
            <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;

これで完成!!Bootstrapの方もちゃんとどうなってるのか把握しないとなぁ🐥

Discussion