# React - TypeScript
# props の型を定義する
React.Component
かReact.FC
を使う
interface IButtonProps {
text: string;
disabled?: boolean; // 任意項目
action: () => void;
}
// クラスコンポーネントの場合
class MyButton extends React.Component<IButtonProps, void> {}
// 関数コンポーネントの場合
const MyButton: React.FC<IButtonProps> = ({ text, action }) => {};
# hook の型を定義する
useState
等にジェネリックを渡す
const [isOk, setIsOk] = React.useState<bool>(false);
# nullable な型にする
const [isOk, setIsOk] = React.useState<bool | null>(null);
# Generic を使って型を作る
interface Props<T> {
items: T[];
renderItem: (item: T) => React.ReactNode;
}
function List<T>(props: Props<T>) {
const { items, renderItem } = props;
return <div>{items.map(renderItem)}</div>;
}
// 利用側
const App = () => {
return (
<List<number>
items={[1, 2, 3, 4]}
renderItem={(item) => <li key={item}>{item.toPrecision(3)}</li>}
/>
);
};
# Enum
下記の場合、Enum は最終的にテキストになる
enum SelectableButtonTypes {
Important = 'important',
Optional = 'optional',
Irrelevant = 'irrelevant',
}
interface IButtonProps {
buttonType: SelectableButtonTypes;
}
const MyButton = (props: IButtonProps) => {};
// 使い方
const App = () => {
return <MyButton buttonType={SelectableButtonTypes.Important} />;
};
# interface か type か
どちらでもほぼ同じことができるが、公式ドキュメント (opens new window)ではなるべく interface を使うべきとの記載あり。
# HTML 要素を拡張する
React.HTMLAttributes
を使う
interface IBorderedBoxProps extends React.HTMLAttributes<HTMLDivElement> {
title: string;
}
const BorderedBox: React.FC<IBorderedBoxProps> = (props) => {
const { children, title, ...divAttributes } = props;
return (
<div {...divAttributes} style={{ border: '1px solid red' }}>
<h1>{title}</h1>
{children}
</div>
);
};
# イベントタイプ
React.MouseEvent
を使う
function eventHandler(event: React.MouseEvent<HTMLAnchorElement>) {
console.log('TEST!');
}
const MyButton = () => {
return <button onClick={eventHandler}></button>;
};