typescript-cheatsheets / react

Cheatsheets for experienced React developers getting started with TypeScript

Home Page:https://react-typescript-cheatsheet.netlify.app

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Question] Should we be using React.FunctionComponentElement type?

devinrhode2 opened this issue · comments

I am just trying to figure out what's a good strategy for the return types of functional react components that return jsx. I'm not a fan of everything being typed as JSX.Element. I did find that React.FunctionComponentElement requires some generics to be passed in, which seems like it might be something we want to use, but not sure.

You should be able to type your function components like this:

import React, { FC } from 'react';

type Props = {
    prop1: string;
    prop2: string;
}

const MyComponent: FC<Props> = ({ prop1, prop2 }) => {
    return (
        <div>{prop1} {prop2}</div>
    )
}

FC is shorthand for FunctionComponent. The Props is the generic value you're passing in.

Is that what you're looking for?

what @hellatan said

This is great, that makes perfect sense, it's just FunctionComponent :)

What should be the return type of MyComponent?

And how would we type <MyComponent prop1={'foo'} prop2={'bar'} />? Is it the same as the return type of MyComponent?

const MyComponent: FC<Props> = ({ prop1, prop2 }): JSX_DIV => {
    const JsxDiv: JSX_DIV = <div>{prop1} {prop2}</div>
    return JsxDiv
}

export const SecondLevelComponent: FC<Props> = (): JSX_MYCOMPONENT {
  const myComponentReturn: JSX_MYCOMPONENT = <MyComponent prop1={'foo'} prop2={'bar'} />
  return myComponentReturn
}

What should these JSX_DIV and JSX_MYCOMPONENT types be?

I'm thinking JSX_MYCOMPONENT might be some sort of React.FunctionComponentElement, but I'm only a few hours in and this jsx typing stuff feels like a super massive black hole

JSX.Element - try to use the TS playground to make it easier to communicate and help you https://www.typescriptlang.org/play?#code/JYWwDg9gTgLgBAKjgQwM5wEoFNkGN4BmUEIcA5FDvmQNwCwAUI7hAHarwCyAngMImRWWVjABcmKjAB0AMV4AeZK24A+OAF44ACgDecMMTABGADT7DAJjgBfcUu4BKcQCkAygA0pAUQA2WEMLw6mo6jHDhcCzs8M6oAB4AIsAAbhpw8gAmKSo6BhDG1nC5ltbyAPRZySphEZQwAK5QrHCxiSmM1oyMWHGQsJFsHHCuWFEZADJYyVg+-OBsgeLYeNJyispqmlpOLR7efgEiGiE1UUMgfAILItgNTS57vv6BafI8c4IvecbqOmQEEAgZEK3wsvzIACNkFBgXAytUGOE6o1mhcPtcYLcUR0gA

my advice - you are going down too far this rabbit hole. newbies often try to type every little thing. this makes for intolerable typescript. follow the style of this guide - annotate where necessary and let typescript infer the rest.

by using FC/FunctionComponent, that type is already returning a ReactElement. You don't need to add an actual return type like you have outlined with FC<Props> = (): JSX_MYCOMPONENT - that is redundant.

That's one great thing (of many!) about TypeScript is that you can create a type that has both the arguments and the return type in one value so you don't always have to declare both with your function. A good example of this are event handlers declared by react. Let's take mouse event handler for example. React has both MouseEvent and MouseEventHandler. They are almost identical except the latter extends from the former.

const handleClick = (event: MouseEvent<HTMLAnchorElement>): void => { ... }

is equivalent to

const handleClick: MouseEventHandler<HTMLAnchorElement> = event => { ... }
commented

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions!

closing as stale