はじめに
4月からTypeScriptとReactを実務で使い始めました。
それまではJavaメインで、JavaScriptはjQueryとかしか書いていませんでした。
なので始めたてのひよっこTypeScripterです。
少しずつ覚えてきてはいますが、まだまだわからないことだらけです。
あれ、あの型って何使えばいいんだっけ、何度もググることが多いので覚書としてよく使うであろう型定義をまとめてみました。
コンポーネント関連の型
コンポーネントを定義するときに使うであろう型を確認します。
関数コンポーネントの型
型定義
React.FC<P>
または
React.FunctionComponent<P>
FC
はFunctionComponent
の別名です。
P
はpropsの型を定義します。
使用例
import React from 'react';
type Props = {
name: string;
age: number;
};
const MyComponent: React.FC<Props> = ({ name, age }) => {
return (
<h1>
{name}さん({age}才)
</h1>
);
};
export default MyComponent;
childrenの型
型定義
React.ReactNode
基本的にpropsの型は自身で決められますが、childrenだけは上記の型を使う必要があります。
使用例
import React from 'react';
type Props = {
title: string;
children: React.ReactNode;
};
const MyComponent: React.FC<Props> = ({ title, children }) => {
return (
<>
<h1>{title}</h1>
{children}
</>
);
};
export default MyComponent;
propsを使ってhtmlタグの属性を指定するときの型
これは正直知らなかったのですが、特定の属性を持ったタグを用意したい場合に便利です。
型定義
React.HTMLAttributes<T>
HTMLAttributes
はそのまま使うより、ButtonHTMLAttributes
やInputHTMLAttributes
など、htmlのタグごとに用意されている型を使うほうが、より限定できるので望ましいです。
T
はhtmlの要素が入ります。
ButtonHTMLAttributes
ならHTMLButtonElement
を指定します。
使用例
import React from "react";
type Props = {
title: string;
attrs: React.ButtonHTMLAttributes<HTMLButtonElement>;
};
const MyComponent: React.FC<Props> = ({ title, attrs }) => {
return (
<>
<h1>{title}</h1>
<button {...attrs}>ボタン</button>
</>
);
};
export default MyComponent;
button
タグの属性をpropsを通して渡すことができます。
このコンポーネントを使用する場合は以下のようになります。
import React from "react";
import ReactDOM from "react-dom/client";
import MyComponent from "./MyComponent.tsx";
const buttonAttrs: React.ButtonHTMLAttributes<HTMLButtonElement> = {
type: "button",
name: "myButton",
};
ReactDOM.createRoot(document.getElementById("root")!).render(
<MyComponent attrs={buttonAttrs} title="タイトル" />
);
propsとして渡すオブジェクトの型も属性ごとのHTMLAttributes
を使って指定することで、不正な属性が混入することなく、動的にhtmlタグの属性の制御ができます。
これは覚えておいて損はなさそうです。
React Hooks関連の型
useReducerで使う型
ちょっと複雑ですが、しっかり型定義するとVS Codeなどでは入力補完してくれたりするので、より便利に使えるようになります。
型定義
React.Reducer<S,A>
useReducer
の第1引数に設定する処理に対して使用します。
S
は処理内で使用するstate
、A
は処理内で使用するaction
の型を設定します。
使用例
import React, { useReducer } from "react";
// stateの型
type State = { count: number };
// actionの型
type Action = { type: "increment" } | { type: "decrement" };
// useReducerの第2引数に設定する初期値
const initialState: State = { count: 0 };
// 今回紹介した型
const reducer: React.Reducer<State, Action> = (state, action) => {
switch (action.type) {
case "increment":
return { count: state.count + 1 };
case "decrement":
return { count: state.count - 1 };
default:
return state;
}
};
const MyComponent: React.FC = () => {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<div>
<div>Count: {state.count}</div>
<button onClick={() => dispatch({ type: "increment" })}>+</button>
<button onClick={() => dispatch({ type: "decrement" })}>-</button>
</div>
);
};
export default MyComponent;
useReducer
に設定するreducer
の型を厳密に定義したことで、state
、dispatch
も内部で型推論されるため、値の使用や設定がスムーズに行えるようになります。
useStateに設定する型
これは型というよりもジェネリクスの話になりますが、ユーザー定義の型でuseStateを使いたい場合に有効です。
型定義
useState<S>
S
はstate
の型を設定します。
string
やnumber
などのプリミティブ型の場合は適切に推論してくれるので設定不要です。
使用例
import React, { useState } from "react";
type User = {
name: string;
age: number;
country: string;
};
const MyComponent: React.FC = () => {
const [state, setState] = useState<User>({
name: "John",
age: 22,
country: "America",
});
return (
<div>
<div>{state.name}</div>
<button
onClick={() =>
setState({
name: "Kevin",
age: 20,
country: "Canada",
})
}
>
ボタン
</button>
</div>
);
};
export default MyComponent;
User
型をジェネリクスに設定しています。
これでこのstate
はUser
型しか受け付けなくなるので、不正な値を入れる心配がなくなります。
イベントの型
input
タグのonChange
属性や、form
タグのonSubmit
属性などに設定する関数で受け取るevent
にも適切な型があります。
changeイベント
型定義
React.ChangeEvent<T>
T
にはHTML要素が入ります。これを適切に設定しないと、意図した値を取得できません。
使用例
import React from "react";
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
console.log(event.target.value);
};
const MyComponent: React.FC = () => {
return <input type="text" onChange={handleChange} />;
};
export default MyComponent;
ここではHTMLの要素としてHTMLInputElement
を指定しました。
これにより、input
タグに関連する値がevent.target
から取得できるようになります。
フォームの送信イベント
フォーム送信時、既存のsubmit処理になにか噛ませたりすることはよくあります。
型定義
React.FormEvent<T>
changeイベントのときと同様、T
にはHTMLの要素を入れます。
使用例
import React from "react";
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
console.log("submit done");
};
const MyComponent: React.FC = () => {
return <form onSubmit={handleSubmit}></form>;
};
export default MyComponent;
今回はFormタグなのでHTMLFormElement
をT
として設定しました。
その他のイベント
ほかにもMouseEventやKeyboardEvent、FocusEventなど、いろいろなイベントが用意されています。
基本的な使い方は同じです。型を定義する際にHTMLの要素もジェネリクスに指定します。
まとめ
あれなんだっけな、といちいち調べるのが面倒だったので、ざーっとまとめてみました。
今回は「@types/react」モジュールの「index.d.ts」ファイルの中身をClaude AIに読み込ませ、その中で重要そうなものをピックアップして貰う形で記事を作成しました。
※重要そうな型をピックアップしてもらっただけなので、記事全体は自身が責任をもって執筆しています。
propsを使ってhtmlタグの属性を指定する方法などはまったく知らなかったので良い学びになりました。
まだTypeScriptやり始めなので、もしかするともっとこういう型があるとか、これは使わないよ、とかがあるかもしれません。
その際はぜひ教えていただけますとありがたいです。