1.)JSX.Element、ReactNode、ReactElementの違いは何ですか?
ReactElementとJSX.Element
は、React.createElement直接またはJSXトランスパイルを介して呼び出した結果です。それは持つオブジェクトであるtype、propsとkey。JSX.ElementはReactElement、そのpropsとtypeはタイプを持っているanyので、それらは多かれ少なかれ同じです。
const jsx = <div>hello</div>
const ele = React.createElement("div", null, "hello");
ReactNodeはrender()、クラスコンポーネントの戻り値の型として使用されます。これは、children属性のデフォルトタイプでもありますPropsWithChildren。
const Comp: FunctionComponent = props => <div>{props.children}</div>
React型宣言ではより複雑に見えますが、次と同等です。
type ReactNode = {} | null | undefined;
ほとんどすべてをに割り当てることができますReactNode。私は通常、より強力なタイプを好みますが、それを使用するためのいくつかの有効なケースがあるかもしれません。
2.)クラスコンポーネントのrenderメソッドがReactNodeを返すのに、関数コンポーネントがReactElementを返すのはなぜですか?
tl; dr:コアReactとは関係のない現在のTSタイプの非互換性です。
原則としてrender()、React / JSクラスのコンポーネントは、関数コンポーネントと同じ戻り値の型をサポートします。TSに関しては、さまざまなタイプが、歴史的な理由と下位互換性の必要性のために依然として保持されているタイプの不整合です。
理想的には、有効な戻り値の型はおそらく次のようになります。
type ComponentReturnType = ReactElement | Array<ComponentReturnType> | string | number
| boolean | null
3.)nullに関してこれを解決するにはどうすればよいですか?
いくつかのオプション:
const MyComp1 = ({ condition }: { condition: boolean }) =>
condition ? <div>Hello</div> : null
const MyComp2 = (): JSX.Element => <div>Hello</div>;
const MyComp3 = (): React.ReactElement => <div>Hello</div>;
const MyComp4: React.FC<MyProps> = () => <div>Hello</div>;
注:回避しても、戻り値の型の制限から解放さReact.FC れるわけではありませんJSX.Element | null。
Create React Appは、暗黙的な型定義のようないくつかの癖があるため、最近テンプレートから削除さReact.FCれました{children?: ReactNode}。したがって、React.FC控えめに使用することをお勧めします。
エッジケースでは、回避策としてタイプアサーションまたはフラグメントを追加できます。
const MyCompFragment: FunctionComponent = () => <>"Hello"</>
const MyCompCast: FunctionComponent = () => "Hello" as any
class Example extends Component<ExampleProps> {クラスやconst Example: FunctionComponent<ExampleProps> = (props) => {関数コンポーネント(ExampleProps予想される小道具のインターフェイスはどこですか)のように見えるはずです。そして、これらの型には、戻り値の型を推測できる十分な情報があります。