🛖

【React × Typescript】マウスイベントについて

に公開

初めに

こんにちは!今回は、React × TypeScriptでの 「クリック」や「ホバー」 といったマウスイベントの実装について、あらためて整理してみたいと思います。
マウスイベントとは、マウスカーソルの動きやボタンの操作によって発生する一連のイベントのことを指します。
本記事では、特に使用頻度の高い「クリックイベント」と「ホバー効果」にフォーカスしてまとめてみようと思います!

クリックイベント

基本的なクリックの実装

ボタンがクリックされるたびにクリック回数を数え、表示する例をもとに考えていきます。

import React, { useState } from 'react';

const BasicClickEventHandler = () => {
  const [clickCount, setClickCount] = useState<number>(0);

  const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
    console.log('ボタンがクリックされました!');
    console.log('イベントオブジェクト:', event);
    console.log('クリックされた要素:', event.currentTarget);
    setClickCount(prevCount => prevCount + 1);
  };

  return (
    <div>
      <h3>クリックイベントの例</h3>
      <button onClick={handleClick}>
        クリックしてください ({clickCount})
      </button>
      <p>ボタンがクリックされた回数: {clickCount}</p>
    </div>
  );
};

export default BasicClickEventHandler;

解説

  • useStateフックを使って、クリック回数を管理するための状態変数clickCountを宣言しています。初期値は0です。
  • setClickCountはclickCountを更新するための関数です。
  • 型は <number> と明示しており、clickCount は数値しか入らないようになっています。
  • useState で使う状態名と同じようにイベントハンドラの名前(例えば,onClickとか)もキャメルケースで書く。
  • 引数 event の型について
    • React.MouseEvent<HTMLButtonElement> は「このイベントが <button> 要素に対するマウスイベントである」という型。
    • これにより、TypeScriptの補完が効いて、event.currentTarget や event.preventDefault() などが安全に使える。
SyntheticBaseEventってなーに

SyntheticBaseEventは、異なるブラウザ環境でイベントを一貫性のある形で扱えるようにするための、抽象化されたイベントオブジェクトです。これにより、開発者はブラウザごとの細かな違いを気にすることなく、より効率的にイベント処理を記述できるようになります。

実際の画面はこんな感じ

複数の要素に対してクリックイベントを設定する応用的な例

複数の異なるHTML要素(<button>, <div>, <span>)に対してクリックイベントを設定し、それぞれの動作を確認する例で考えていきたいと思います。

import React from 'react';

const MultipleClickExample = () => {
  // ボタン要素
  const handleButtonClick = (event: React.MouseEvent<HTMLButtonElement>) => {
    console.log('ボタンがクリックされました!');
    console.log('クリックされたボタンのタグ名:', event.currentTarget.tagName);
  };

  // div要素
  const handleDivClick = (event: React.MouseEvent<HTMLDivElement>) => {
    console.log('Div要素がクリックされました!');
    console.log('クリックされたDivのタグ名:', event.currentTarget.tagName);
  };

  // 汎用的なHTML要素(spanタグなど)
  const handleGenericClick = (event: React.MouseEvent<HTMLElement>) => {
    console.log('汎用要素がクリックされました!');
    console.log('クリックされた汎用要素のタグ名:', event.currentTarget.tagName);
  };

  return (
    <div>
      <h2>複数のクリックイベントのデモ</h2>
      <p>異なるHTML要素にクリックイベントを設定した例です。</p>

      {/* ボタンのクリックイベント */}
      <button onClick={handleButtonClick} style={{ margin: '10px', padding: '10px' }}>
        ボタン
      </button>

      {/* divのクリックイベント */}
      <div
        onClick={handleDivClick}
        style={{ border: '1px solid gray', padding: '10px', margin: '10px', cursor: 'pointer' }}
      >
        クリック可能なDiv要素
      </div>

      {/* spanのクリックイベント */}
      <span
        onClick={handleGenericClick}
        style={{ border: '1px dotted gray', padding: '10px', margin: '10px', display: 'inline-block', cursor: 'pointer' }}
      >
        クリック可能なSpan要素
      </span>

      <p>各要素をクリックすると、開発者ツールのコンソールに日本語のログが出力されます。</p>
    </div>
  );
};

export default MultipleClickExample;

解説

  • 要素ごとのマウスイベント型の使い分けができる。
    • HTMLButtonElement, HTMLDivElement, HTMLElementなど

実際の画面

ホバー効果

ユーザーがマウスカーソルを特定の要素(ここでは div ボックス)に「乗せた」「外した」かを検知し、背景色の変化やログ出力でホバー状態を可視化できる例で考えていきたいと思います。

import React, { useState } from 'react';

const HoverEffectExample = () => {
  const [isHovered, setIsHovered] = useState<boolean>(false);

  // マウスが要素に乗ったときのハンドラ
  const handleMouseEnter = (event: React.MouseEvent<HTMLDivElement>) => {
    console.log('マウスが要素に乗りました!', event.currentTarget.tagName);
    setIsHovered(true); // ホバー状態をtrueに更新
  };

  // マウスが要素から外れたときのハンドラ
  const handleMouseLeave = (event: React.MouseEvent<HTMLDivElement>) => {
    console.log('マウスが要素から外れました!', event.currentTarget.tagName);
    setIsHovered(false); // ホバー状態をfalseに更新
  };

  const boxStyle: React.CSSProperties = {
    width: '200px',
    height: '100px',
    border: '2px solid #333',
    display: 'flex',
    justifyContent: 'center',
    alignItems: 'center',
    fontSize: '18px',
    fontWeight: 'bold',
    transition: 'background-color 0.3s ease', // スムーズな色の変化
    backgroundColor: isHovered ? '#ADD8E6' : '#E0FFFF', // ホバー状態に応じて色を変更
    cursor: 'pointer',
    margin: '20px auto',
  };

  return (
    <div>
      <h2>ホバー効果のデモ</h2>
      <p>以下のボックスにマウスカーソルを乗せてみてください。</p>

      <div
        style={boxStyle}
        onMouseEnter={handleMouseEnter}
        onMouseLeave={handleMouseLeave}
      >
        {isHovered ? 'ホバー中!' : 'ここにマウスを置いてね'}
      </div>

      <p>現在のホバー状態: {isHovered ? '✅ ホバーしています' : '❌ ホバーしていません'}</p>
      <p>マウスを乗せたり外したりすると、コンソールにもログが出力されます。</p>
    </div>
  );
};

export default HoverEffectExample;

解説

  • useState フックを使って、コンポーネント内で「ボックスがホバーされているかどうか」を示す状態変数 isHoveredを定義しています。
  • 初期値は false で、これは「最初はホバーされていない」ことを意味します。
  • event: React.MouseEvent<HTMLDivElement> は、このイベントがマウスイベントであり、対象となる要素が HTMLDivElement であることを示す型情報です。
  • onMouseEnter/onMouseLeaveで要素への進入・離脱を制御しています。

実際の画面

まとめ

  • React.MouseEvent<HTMLButtonElement>React.MouseEvent<HTMLDivElement> など、要素に応じた適切な型を使用することで、TypeScriptの型安全性と補完機能を最大限活用できます。

  • イベントハンドラの実装において、onClick でクリックイベント、onMouseEnter / onMouseLeave でホバー効果を実装することができます。

Discussion