6-3. イベントハンドラの型を定義する

イベントハンドラに正しい型を指定する方法を学びます

React - 第4章: TypeScript + React

課題:イベントハンドラの型を定義しよう

クリックやフォーム送信などのイベントにも、TypeScriptで型を指定できます。 正しい型を使うと、イベントオブジェクトを安全に扱えます。

やること

  1. 1.入力変更イベント(ChangeEvent)の型を指定する
  2. 2.フォーム送信イベント(FormEvent)の型を指定する
  3. 3.名前を入力して送信すると、メッセージを表示する

イベントハンドラの型

まず、Reactから型をインポートします:

import { ChangeEvent, FormEvent } from 'react';

入力変更イベントの型:

const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
  setName(e.target.value);
};

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

const handleSubmit = (e: FormEvent<HTMLFormElement>) => {
  e.preventDefault();  // ページリロードを防ぐ
  // 処理
};

ポイント:イベントの型を指定すると、e.target.value などが正しく補完され、typoを防げます。

期待される出力

名前を入力してください
[入力フィールド: 太郎]
[送信]

こんにちは、太郎さん!
import { useState } from 'react';
// ここにChangeEventとFormEventをインポートしてください


function App() {
  const [name, setName] = useState<string>("");
  const [message, setMessage] = useState<string>("");
  
  // ここにeの型を追加してください
  const handleChange = (e) => {
    setName(e.target.value);
  };
  
  // ここにeの型を追加してください
  const handleSubmit = (e) => {
    e.preventDefault();
    setMessage(`こんにちは、${name}さん!`);
    setName("");
  };
  
  return (
    <div style={{ padding: '20px', maxWidth: '400px', margin: '0 auto' }}>
      <h2>名前入力フォーム</h2>
      
      <form onSubmit={handleSubmit} style={{ marginTop: '20px' }}>
        <label style={{ display: 'block', marginBottom: '10px' }}>
          名前を入力してください
        </label>
        
        <input 
          type="text"
          value={name}
          onChange={handleChange}
          placeholder="名前"
          style={{ 
            width: '100%',
            padding: '10px',
            fontSize: '16px',
            border: '1px solid #ccc',
            borderRadius: '4px'
          }}
        />
        
        <button 
          type="submit"
          style={{ 
            marginTop: '15px',
            padding: '10px 30px',
            fontSize: '16px',
            backgroundColor: '#007bff',
            color: 'white',
            border: 'none',
            borderRadius: '4px',
            cursor: 'pointer'
          }}
        >
          送信
        </button>
      </form>
      
      {message && (
        <div style={{ 
          marginTop: '30px',
          padding: '15px',
          backgroundColor: '#d4edda',
          border: '1px solid #c3e6cb',
          borderRadius: '4px',
          fontSize: '18px',
          fontWeight: 'bold',
          color: '#155724'
        }}>
          {message}
        </div>
      )}
    </div>
  );
}

export default App;