TL;DR
このページでは、Next.js と TypeScript を使用した React イベントの実装方法について解説します。その過程で、イベントが React と一緒にどのように機能するのか、そしてそれらを TypeScript で型付けする際の考え方を調べてみましょう。
開発環境 | バージョン |
---|---|
Next.js | 13.4.4 |
TypeScript | 5.0.4 |
Emotion | 11.11.0 |
React | 18.2.0 |
イベントとは?
React のイベントシステムの前に、「イベント」について解説します。
イベントとは、あなたが何かを行うことで、コンピュータやプログラムが反応するための「トリガー(引き金)」のようなものです。例えば、ボタンをクリックしたり、キーボードのキーを押したり、マウスを動かしたりすると、それらはすべて「イベント」と呼ばれます。
それでは、このイベントを楽しい例え話で考えてみましょう。あなたが公園で遊んでいて、フリスビーを投げるとします。あなたがフリスビーを投げる行為は「イベント」です。そして、あなたの友達(ここではコンピュータやプログラムと考えてみてください)がそれを見て、フリスビーを追いかけるという反応を起こします。
ここで、フリスビーを投げる行為が「イベント」であり、フリスビーを追いかける行為が「イベントハンドラ(イベント処理)」となります。フリスビーを投げたときに何が起こるのか(友達がフリスビーを追いかける)は、事前に決めておくことができます。これがプログラミングにおける「イベントハンドリング」の基本的な考え方です。
なので、例えばボタンをクリックしたら、何か特定の動作をするようにプログラミングすることができます。この特定の動作が「イベントハンドラ」で、それをプログラムすることを「イベントハンドリング」と呼びます。
React イベントシステムとは?
React のイベントシステムは、ブラウザの標準イベントシステムを抽象化したもので、各種ブラウザのイベントの違いを吸収し、一貫したイベントハンドリングの体験を提供します。JavaScript のイベントリスナーとは違い、React のイベントはキャメルケースで書かれ、JSX に直接渡されます。
React では様々な種類のイベントに対応しています。以下の表はその一部です。
イベント種別 | 例 | 用途 |
---|---|---|
クリックイベント | onClick |
ボタンやリンクのクリック、要素上でのマウスダウン&アップイベントに対応 |
フォームイベント | onChange , onSubmit |
入力値の変更、フォームの送信に対応 |
キーボードイベント | onKeyDown , onKeyUp |
キーボードのキー押下、キー解放に対応 |
マウスイベント | onMouseOver , onMouseOut |
マウスカーソルの要素上への入出に対応 |
フォーカスイベント | onFocus , onBlur |
要素のフォーカス取得、フォーカス失いに対応 |
スクロールイベント | onScroll |
スクロール操作に対応 |
タッチイベント | onTouchStart , onTouchEnd |
タッチデバイス(スマートフォンやタブレット)のタッチ開始、タッチ終了に対応 |
ドラッグ&ドロップイベント | onDrag , onDrop |
ドラッグ操作、ドロップ(ドラッグ中の要素の放下)に対応 |
これらのイベントハンドラは、関数を受け取り、その関数内でイベントに対する動作を定義します。イベントハンドラは、通常、React のコンポーネントの中で定義されます。
基本的な onClick イベントのハンドラは以下のようになります。
type Props = {
text: string
}
const ButtonComponent = ({ text }: Props) => {
const handleClick = () => {
console.log('Button clicked!')
}
return <button onClick={handleClick}>{text}</button>
}
このソースコードでは、ButtonComponent
というボタンコンポーネントを作成しています。handleClick
関数は、ボタンがクリックされたときにコンソールにメッセージを表示します。
Next.js で、React イベントを実装
Next.js での React イベントの取り扱いは、通常の React アプリと同じです。それでは、より具体的な例を見てみましょう。
次のソースコードは、テキストフィールドからユーザーの入力を受け取り、onChange イベントを使って入力を state で管理するコンポーネントです。
// components/InputField.tsx
import { useState } from 'react'
type Props = {
placeholder: string
}
const InputField = ({ placeholder }: Props) => {
const [value, setValue] = useState('')
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setValue(e.target.value)
}
return <input type="text" placeholder={placeholder} value={value} onChange={handleChange} />
}
export default InputField
上記のコードでは、useState
フックを使ってユーザーの入力を追跡します。handleChange
関数では、イベントオブジェクト e
を受け取り、その value
プロパティを setValue
に渡して state を更新しています。
高度なイベント処理
React のイベント処理の考え方を更に広げてみましょう。例えば、複数の input フィールドの値を一度に管理するためのハンドラを作成します。
// components/MultiInputField.tsx
import { useState } from 'react'
type FormData = {
firstName: string
lastName: string
}
const MultiInputField = () => {
const initialFormData: FormData = {
firstName: '',
lastName: '',
}
const [formData, setFormData] = useState(initialFormData)
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setFormData({
...formData,
[e.target.name]: e.target.value,
})
}
return (
<>
<input type="text" name="firstName" value={formData.firstName} onChange={handleChange} />
<input type="text" name="lastName" value={formData.lastName} onChange={handleChange} />
</>
)
}
export default MultiInputField
ここでは、複数の入力フィールド(名前と姓)の値を一つの state オブジェクトで管理します。各入力フィールドは固有の name
属性を持ち、この name
属性は handleChange
関数内で利用されています。
Emotion での実装
Emotion は、CSS-in-JS ライブラリの一つで、React コンポーネント内で CSS を直接記述することができます。それでは、Emotion を使ってスタイル付きのボタンを作成し、そのボタンがクリックされたときに特定のアクションを実行するような例を見てみましょう。
// components/StyledButton.tsx
/** @jsxImportSource @emotion/react */
import { css } from '@emotion/react'
type Props = {
text: string
}
const buttonStyles = css`
padding: 10px 20px;
background-color: #0070f3;
border: none;
color: #fff;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.2s ease;
&:hover {
background-color: #0051bb;
}
`
const StyledButton = ({ text }: Props) => {
const handleClick = () => {
console.log('Styled button clicked!')
}
return (
<button css={buttonStyles} onClick={handleClick}>
{text}
</button>
)
}
export default StyledButton
ここでは、ボタンのスタイルを buttonStyles
という定数に定義し、それをボタンコンポーネントに適用します。そして、ボタンがクリックされたときに handleClick
関数が呼び出され、コンソールにメッセージが出力されます。
以上が、Next.js と TypeScript で React のイベント処理を実装する方法についてのガイドでした。これらの概念を理解して使いこなすことで、よりリッチでインタラクティブなユーザーインターフェースを構築することができます。