Skip to content

イベントとフォームの処理

公開日:December 8, 2024更新日:December 8, 2024
ReactTypeScriptCoding📄

Reactでイベントを処理する際にTypeScriptを使用すると、イベントオブジェクトに型を付けることでコードの安全性が向上します。この章では、Reactのイベント型定義、フォームイベントの取り扱い、ユーザー入力のバリデーションと型について解説します。

Reactイベントの型定義

Reactでは、イベントオブジェクトは独自の型を持っています。TypeScriptを使用することで、イベントの型を明確に定義できます。

基本的なイベントの型定義

Reactのイベント型は、React.SyntheticEventをベースにしています。たとえば、クリックイベントの場合:

tsx
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
  console.log('Button clicked:', event.currentTarget);
};

const App = () => {
  return <button onClick={handleClick}>Click me</button>;
};

export default App;

主なイベント型

  • MouseEvent: マウスイベント(クリックやホバー)
  • KeyboardEvent: キーボードイベント(キー入力)
  • ChangeEvent: フォームの入力値変更イベント
  • SubmitEvent: フォームの送信イベント

型定義の対象となる要素はジェネリクスで指定します(例:HTMLInputElement, HTMLFormElementなど)。

キーボードイベントの例

tsx
const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
  if (event.key === 'Enter') {
    console.log('Enter key pressed');
  }
};

const App = () => {
  return <input type="text" onKeyDown={handleKeyDown} />;
};

export default App;

フォームイベントの取り扱い

フォームの入力処理には、React.ChangeEventReact.FormEventを使用します。以下は入力値を管理する例です。

入力イベントの型定義

tsx
import { useState } from 'react';

const App = () => {
  const [value, setValue] = useState<string>('');

  const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    setValue(event.target.value);
  };

  return (
    <div>
      <input type="text" value={value} onChange={handleChange} />
      <p>Current Value: {value}</p>
    </div>
  );
};

export default App;

フォーム送信イベントの型定義

フォームの送信時には、React.FormEventを使用します。

tsx
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
  event.preventDefault();
  console.log('Form submitted');
};

const App = () => {
  return (
    <form onSubmit={handleSubmit}>
      <button type="submit">Submit</button>
    </form>
  );
};

export default App;

ユーザー入力のバリデーションと型

ユーザー入力のバリデーションを型と組み合わせることで、安全性を高めたコードを記述できます。

バリデーションの基本

以下は、簡単なバリデーションの例です。

tsx
const App = () => {
  const [email, setEmail] = useState<string>('');
  const [error, setError] = useState<string | null>(null);

  const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    const value = event.target.value;
    setEmail(value);

    if (!value.includes('@')) {
      setError('Invalid email address');
    } else {
      setError(null);
    }
  };

  return (
    <div>
      <input type="email" value={email} onChange={handleChange} />
      {error && <p style={{ color: 'red' }}>{error}</p>}
    </div>
  );
};

export default App;

型で制約を強化する

型を使って入力データの形式を制約することも可能です。

tsx
interface FormData {
  username: string;
  age: number;
}

const App = () => {
  const [formData, setFormData] = useState<FormData>({ username: '', age: 0 });

  const handleChange = (
    event: React.ChangeEvent<HTMLInputElement>
  ) => {
    const { name, value } = event.target;
    setFormData({
      ...formData,
      [name]: name === 'age' ? Number(value) : value,
    });
  };

  return (
    <form>
      <input
        type="text"
        name="username"
        value={formData.username}
        onChange={handleChange}
      />
      <input
        type="number"
        name="age"
        value={formData.age}
        onChange={handleChange}
      />
      <pre>{JSON.stringify(formData, null, 2)}</pre>
    </form>
  );
};

export default App;