はじめに
reactの型定義ファイルには普段の開発では見かけることの少ない型が多く定義されています。
これらを使いこなすことでanyを使わずにきれいにコンポーネントを定義できるケースがあります。
今回は3つシチュエーションとそのときに使うと便利な型をサンプルコードと合わせて紹介します。
propsで要素を受け取って表示したいとき
- propsの型に
React.ReactNodeを使う
interface Props1 {
leftElement: React.ReactNode;
rightElement: React.ReactNode;
}
const Example1:React.FC<Props1> = ({leftElement, rightElement}) => (
<div>
<div>{leftElement}</div>
<div>{rightElement}</div>
</div>
)
const Main:React.FC = () => (
<Example1 leftElement={<p>left</p>} rightElement={'right'} />
)
React.ReactNodeはReactElement | number | string | boolean | undefined | nullと定義されています。1
React.ReactElementはタグで囲んだ要素(例:<p>要素</p>)を示します。
Example1のコードではleftElementやrightElementの型にReact.ReactNodeを指定することで、文字列や数値,<p>left</p>のようなReactElementを受け取ることができます。
タグ名をpropsで受け取って動的に変更したいとき
- propsの型に
React.ElementTypeを使う
interface Props2 {
tag?: React.ElementType;
}
const Example2: React.FC<Props2> = ({tag: Tag = 'div', children}) => (
<Tag>{children}</Tag>
)
const Dummy: React.FC = () => (
<p>dummy</p>
)
const Main2: React.FC = () => (
<>
<Example2>div</Example2> {/* <div>div</div> */}
<Example2 tag={'p'}>p</Example2> {/* <p>p</p> */}
<Example2 tag={Dummy}></Example2> {/* <Dummy></Dummy> => <p>dummy</p> */}
</>
)
React.ElementTypeは'span'や'div'などHTMLタグの文字列 | React.ComponentClass | React.FCと定義されています。1
React.ComponentClassはReact.Componentを継承したクラスのことで、クラスコンポーネント形式で書かれたコンポーネントの型はReact.ComponentClassになります。
Example2のコードではpropsのtagにReact.ElementTypeを指定していおり、tagは'p'などのHTMLタグだけでなく独自に定義したコンポーネントを受け取ることもできます。
HTML属性と同じpropsを持ったコンポーネントを作りたいとき
-
React.DetailedHTMLProps<React.HogeHTMLAttributes<HTMLHogeElement>,HTMLHogeElement>でHTML属性の型を取得して、propsを定義する
type Props3 = {
name: string
} & React.DetailedHTMLProps<React.AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>
const Example3: React.FC<Props3> = ({name, href, ...props}) => {
return <a href={href} {...props}>{name}</a>
}
const Main3: React.FC = () => (
<Example3 name={'main3'} href={'google.com'} />
)
React.DetailedHTMLPropsはジェネリックスに応じてHTML属性のそれぞれの型を示します。
見出し下に示した文のHogeを型定義ファイルで定義された、それぞれのHTMLタグに応じた名前にすれば取得できます。
例えば、aタグであればAnchor、formタグであればFormになります。