joppot

コピペで絶対動く。説明を妥協しない

プログラミング

reactで最もシンプルなドロップダウンメニューを作成

投稿日:2018年11月16日 更新日:


概要

みなさんこんにちはcandleです。今回はreactで最もシンプルなドロップダウンメニューを作ってみたいと思います。

前提

  1. Reactの知識がある

準備

以下のコマンドでreactプロジェクトを作成します。

create-react-app hello-menu

src/App.jsを開いて、とりあえずこうしておきます。

import React, { Component } from 'react'

class App extends Component {
  render() {
    return (
      <div>
        <p>hello menu</p>
      </div>
    )
  }
}

export default App

srcフォルダの中にcomponentsフォルダを作ります。

mkdir src/components

src/componentsフォルダにDropDownMenu.jsファイルを作ります。

touch src/components/DropDownMenu.js

これで準備が整いました。

ドロップダウンメニューの作成

src/components/DropDownMenu.jsを開いて、以下を書き込みます。

import React from 'react'

class DropDownMenu extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      listOpen: false,
    }
  }

  toggleList() {
    this.setState(prevState => ({
      listOpen: !prevState.listOpen,
    }))
  }

  handleClickMenu(val) {
    this.setState({
      listOpen: false,
    })
    alert(val)
  }

  render() {
    const { listOpen } = this.state
    return (
      <div style={styles.dropDownMenu}>
        <div onClick={this.toggleList.bind(this)} style={styles.menuButton}>
          menu
        </div>
        {listOpen && (
          <div style={styles.menuBox}>
            <div style={styles.menuContent}>
              <div onClick={this.handleClickMenu.bind(this, 1)}>menu 1</div>
            </div>
            <div style={styles.menuContent}>
              <div onClick={this.handleClickMenu.bind(this, 2)}>menu 2</div>
            </div>
            <div style={styles.lastMenuContent}>
              <div onClick={this.handleClickMenu.bind(this, 3)}>menu 3</div>
            </div>
          </div>
        )}
      </div>
    )
  }
}

const styles = {
  dropDownMenu: {
    position: 'relative',
  },
  menuButton: {
    display: 'inline',
    cursor: 'pointer',
    border: '1px solid black',
    padding: '3px 5px',
  },
  menuBox: {
    position: 'absolute',
    top: '23px',
    width: '120px',
    zIndex: 1,
    cursor: 'pointer',
    border: '1px solid black',
  },
  menuContent: {
    padding: '3px 5px',
    borderBottom: '1px solid black',
  },
  lastMenuContent: {
    padding: '3px 5px',
  },
}

export default DropDownMenu

そしたら、src/App.jsを開いて、このように編集します。

import React, { Component } from 'react'
import DropDownMenu from './components/DropDownMenu'

class App extends Component {
  render() {
    return (
      <div>
        <p>hello menu</p>
        <DropDownMenu />
      </div>
    )
  }
}

export default App

サーバを起動します。

yarn run start

“menu”ボタンを押すとメニューが表示されて、もう一度”menu”ボタンを押すと閉じます。
メニューのリストをクリックするとアラートが表示れ、メニューが閉じます。

メニュー外をクリックして閉じる

“menu”ボタンを押した後、再度閉じるにはもう1度”menu”ボタンを押す必要がありますが、多くのサイトはそれ以外のページをクリックすれば簡単に閉じれるようになっていることが多いです。

これはライブラリを使えば簡単に作ることができます。

yarn add react-onclickoutside

src/components/DropDownMenu.jsを開いて編集します。

import onClickOutside from 'react-onclickoutside'

をファイルのトップに記述します。

新たに関数を作成します。

  handleClickOutside() {
    this.setState({
      listOpen: false,
    })
  }

一番下のexport default DropDownMenu

export default onClickOutside(DropDownMenu)

に変更して終わりです。ブラウザで確認してみてください。メニューを開いた後、外部をクリックするとメニューが閉じますね。

これが完成したコードです。

import React from 'react'
import onClickOutside from 'react-onclickoutside'

class DropDownMenu extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      listOpen: false,
    }
  }

  toggleList() {
    this.setState(prevState => ({
      listOpen: !prevState.listOpen,
    }))
  }

  handleClickMenu(val) {
    this.setState({
      listOpen: false,
    })
    alert(val)
  }

  handleClickOutside() {
    this.setState({
      listOpen: false,
    })
  }

  render() {
    const { listOpen } = this.state
    return (
      <div style={styles.dropDownMenu}>
        <div onClick={this.toggleList.bind(this)} style={styles.menuButton}>
          menu
        </div>
        {listOpen && (
          <div style={styles.menuBox}>
            <div style={styles.menuContent}>
              <div onClick={this.handleClickMenu.bind(this, 1)}>menu 1</div>
            </div>
            <div style={styles.menuContent}>
              <div onClick={this.handleClickMenu.bind(this, 2)}>menu 2</div>
            </div>
            <div style={styles.lastMenuContent}>
              <div onClick={this.handleClickMenu.bind(this, 3)}>menu 3</div>
            </div>
          </div>
        )}
      </div>
    )
  }
}

const styles = {
  dropDownMenu: {
    position: 'relative',
  },
  menuButton: {
    display: 'inline',
    cursor: 'pointer',
    border: '1px solid black',
    padding: '3px 5px',
  },
  menuBox: {
    position: 'absolute',
    top: '23px',
    width: '120px',
    zIndex: 1,
    cursor: 'pointer',
    border: '1px solid black',
  },
  menuContent: {
    padding: '3px 5px',
    borderBottom: '1px solid black',
  },
  lastMenuContent: {
    padding: '3px 5px',
  },
}

export default onClickOutside(DropDownMenu)

まとめ

自分のプロジェクトで利用する時はデザインはもちろんですが、他のライブラリと組み合わせて使うことになるでしょう例えばreact-routerのリンクとか。是非挑戦して、使いやすいドロップダウンメニューを作成してみてください。

スポンサードリンク

「為になったなぁ」と思ったら、シェアお願いします。

-プログラミング
-,

執筆者:


comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

関連記事

Mysqlのdatetime型とtimestanp型で保存されているデータを年月日だけを指定して任意の日にちのデータを取得する方法

概要 みなさんこんにちはcandleです。今日はmysqlのdatetime型とtimestanp型におさめられているデータの取得を紹介します。 datetimeやtimestanpは多くの場合下のよ …

ruby on rails4でtwitter bootstrap 3のgemを使用してscaffoldを作成する

概要 みなさんこんにちはcandleです。今回はrails4上でtwitterbootstrap3のgemを使ってscaffoldしてみたいと思います。 scaffoldとはご存知のようにいわゆるwe …

railsのcoffee scriptをurl判定をして実行をする方法

概要 みなさんこんにちはcandleです。 今回はcoffeescriptを任意のURLで実行する様にする関数を作ります。 というのはrailsは最終的にassetspiplineでjavascrip …

Hiragino Sansフォントウェイトのcss書き方まとめ

概要 みなさんこんにちはcandleです。今回はHiragino Sansのcssの書き方を紹介します。 Hiragino Sansの特徴はフォントの太さを1から9段階まで変えられることです。 一方で …

fabricのsshのネットワーク設定でパスワードか公開鍵を使って認証する

概要 皆さん今日はcandleです。今回はsshを使ったfabricの設定をしましょう。 一般にsshにはパスワード認証と公開鍵認証があるので、そのどちらも試してみましょう。 もちろんセキュリティ面で …


ベンチャー企業のCTOをやってます。大学時代にプログラミングを始め、javaから入門し、C++へて、PHPへと進み、会社ではRailsを使用。自動化が大好きなプログラマー