score:93
Thanks all for the answers. They are correct but I was looking for a more detailed version. I did some more research and found this on React+TypeScript Cheatsheets on GitHub.
Function Components
These can be written as normal functions that take a props argument and return a JSX element.
type AppProps = { message: string }; /* could also use interface */
const App = ({ message }: AppProps) => <div>{message}</div>;
What about React.FC
/React.FunctionComponent
?
You can also write components with React.FunctionComponent
(or the shorthand React.FC
):
const App: React.FC<{ message: string }> = ({ message }) => (
<div>{message}</div>
);
Some differences from the "normal function" version:
It provides typechecking and autocomplete for static properties like displayName
, propTypes
, and defaultProps
- However, there are currently known issues using defaultProps
with React.FunctionComponent
. See this issue for details - scroll down to our defaultProps
section for typing recommendations there.
It provides an implicit definition of children (see below) - however there are some issues with the implicit children type (e.g. DefinitelyTyped#33006), and it might be considered a better style to be explicit about components that consume children, anyway.
const Title: React.FunctionComponent<{ title: string }> = ({
children,
title
}) => <div title={title}>{children}</div>;
In the future, it may automatically mark props as readonly, though that's a moot point if the props object is destructured in the parameter list.
React.FunctionComponent
is explicit about the return type, while the normal function version is implicit (or else needs additional annotation).
In most cases, it makes very little difference which syntax is used, but the
React.FC
syntax is slightly more verbose without providing clear advantage, so precedence was given to the "normal function" syntax.
score:11
Since you are using React and TypeScript, you should always use the first pattern, as it will ensure that your component is more strictly typed since it implies that the PrintName
will be of type React Functional Component, and it takes in props of type Props
.
const PrintName: React.FC<Props>
You may read the full interface definition for Functional Components on the React TypeScript typings repository.
The second example you have provided does not provide any form of typings, except that it is a function that takes a set of parameters of type Props
, and that it can return anything in general.
Therefore, writing
const PrintName2 = (props:Props)
is akin to
const PrintName2: JSX.Element = (props:Props)
as TypeScript is definitely unable to automatically infer that it is a Functional Component.
score:17
Best solution:
The second approach + a return type
const PrintName2 = ({ prop1, prop2 }: Props): JSX.Element => { /** */}
This gives you complete control over the Props and is more explicit (there is no hidden magic).
Link to GitHub PR to remove React.FC
Kent C Dodds has some thoughts why this is here
Sub-optimal solution:
The first version (React.FC) will add a few types for you - they come from the React Typings
interface FunctionComponent<P = {}> {
(props: PropsWithChildren<P>, context?: any): ReactElement | null;
propTypes?: WeakValidationMap<P>;
contextTypes?: ValidationMap<any>;
defaultProps?: Partial<P>;
displayName?: string;
}
This approach is useful for a few reasons but an obvious one is if your component has children, then you don't need to manually add a children
prop. It's not great because there are issues with default props and many components don't have children.
score:65
React.FC
is not the preferable way to type a React component, here's a link.
I personally use this type:
const Component1 = ({ prop1, prop2 }): JSX.Element => { /*...*/ }
Short list of React.FC
cons:
- Provides an implicit definition of children, even if your component doesn't need to have children. That might cause an error.
- Doesn't support generics.
- Doesn't work correctly with
defaultProps
.
Source: stackoverflow.com
Related Query
- TypeScript and React - children type?
- How to use refs in React with Typescript
- Typescript react - Could not find a declaration file for module ''react-materialize'. 'path/to/module-name.js' implicitly has an any type
- PropTypes in a TypeScript React Application
- Set types on useState React Hook with TypeScript
- Default property value in React component using TypeScript
- Importing images in TypeScript React - "Cannot find module"
- TypeScript React.FC<Props> confusion
- How to specify (optional) default props with TypeScript for stateless, functional React components?
- Extending HTML elements in React and TypeScript while preserving props
- How to define css variables in style attribute in React and typescript
- Typescript - "Cannot find name" errors in React components
- Cannot find namespace 'ctx' error when creating Context with react - typescript
- How do I restrict the type of React Children in TypeScript, using the newly added support in TypeScript 2.3?
- Using state in react with TypeScript
- TypeScript workaround for rest props in React
- What is the TypeScript return type of a React stateless component?
- React - using TypeScript vs Flow vs?
- React 18 TypeScript children FC
- React Router - Typescript errors on withRouter after updating version
- Typescript types for React checkbox events and handlers?
- allow typescript compiler to call setState on only one react state property
- VSCode prettier adds `value` to imports in TypeScript React
- React + TypeScript usage of className prop
- React TypeScript 16.8 How to make useEffect() async
- React with Typescript -- Generics while using React.forwardRef
- interface states and props in typescript react
- React with Typescript - Type { } is missing the following properties from type
- React component type in TypeScript
- react typescript testing TypeError: MutationObserver is not a constructor
More Query from same tag
- Can I Fastclick ReactJS running in Cordova
- Populating reaxt ag grid after API call
- Passing a child component to an API component
- How to fix state updating in react?
- Global variables in arrow function components
- How to have the children affect the parent in React?
- Redux dispatch actions in response to actions
- Map the data according to image in react js
- add icon to header navBar (I am not getting that how to add icon on the most left in my NavBar)
- Creating custom pagination, but next and prev buttons are not working
- NextJS - Google font is not loading or displaying on the website
- Don't know why i get React Maximum call stack size exceeded
- is requestAnimationFrame belong to microtask or macrotask in main thread task management? if not, how can we categorize this kind of render side task
- How to automatically change text depending on boolean value in JSON file
- mapStateToProps initial value from props, then only state
- How to give border to this react tooltip and remove the arrow?
- Ant Design and React Testing Library
- Assigning a unique key id using React and Dexie?
- JS Object Update + React Reducer
- Puppeteer tests fail when running in headless mode in react application
- Form with redux in react
- You are running `create-react-app` 4.0.1, which is behind the latest release (4.0.3)
- Function firing twice on click in React component
- Adding an icon left of primaryText in Material UI's <ListItem>
- Parent State -> Child Component -> Render Component with onClick not working
- Function is not defined, but it is defined. React and Javascript
- failed to get state value in render of jsx
- Reset count function in counter app not setting count to 0
- Where to put other class functions in a hook?
- Webpack Error React & ES6 Previously working under Babelify