By invoking them between the opening and closing tags of a JSX element, you can use React children for entering data into a component.
The React children
prop is an important concept for creating reusable components because it allows components to be constructed together.
However, a common issue with using React with Typescript is figuring out which data type to use with React children since Typescript is a strongly typed library. So, in this article, we will learn how to utilize props with React children in Typescript.
Using React children
props
Before learning how to use Typescript with React children, let’s refresh our memories on how to use the React children
props and how they work.
What are React props?
Props is simply an abbreviation for properties. In React, we utilize props to send data from one component to another (from a parent component to a child component or multiple children components).
They come in handy when you want the data flow in an app to be dynamic. Below is an example of using props to pass data using props.
function House(props) { return <h2>I am a { props.type }!</h2>; } function Room() { return ( <> <h1>Do you know my room number?</h1> <House type="duplex" /> </> ); }
Here, we passed data to the type
property in the House
component. This property type
is called a prop. In this example, the parent component is Room
, while the child component is House
.
The type
property we passed then renders in the House
component to return I am a duplex
.
What are React children
props?
The ability for components to receive and render children
props is one of React’s most valuable features. It makes creating reusable components insanely simple. Simply encapsulate props.children
with some markup or action and you’re done:
function House(props) { return <h2>I am a { props.children }!</h2>; } function Room() { return ( <> <h1>Do you know my room number?</h1> <House type="duplex" /> </> ); } const Panel = (props) => <div className="Panel"> {props.children} </div>
Using React children
props with Typescript
Typescript is a type-strict JavaScript library, which means you must define the types for your React children
props, and there are different methods of declaring types for React children
props. Let’s learn some of them.
Using the FC
type
FC
is a standard React type used in arrow function components, also known as the FunctionComponent
type.
Here’s an illustration:
type Props = { title: string, }; const Page: React.FC<Props> = ({ title, children, }) => ( <div> <h1>{title}</h1> {children} </div> );
FC
is a general type that accepts all component props and their individual types. In this example, we supplied a Props
type alias with a title
prop.
It’s worth noting that you don’t define the term children
in Props
, since it’s already defined in the functional component type.
Defining the children
prop type explicitly
If we declare the children
prop type directly, we will have different options to set for its type. Let’s take a look at how we can declare the children
prop type directly.
Using a JSX element
Consider the code sample where we used JSX elements below:
type Props = { title: string, children: JSX.Element, }; const Page = ({ title, children }: Props) => ( <div> <h1>{title}</h1> {children} </div> );
Here, children
are a necessary field. To make this optional for the component’s consumer, we can include a question mark (?
) before the type annotation, as seen in the example below:
type Props = { title: string; children?: JSX.Element; };
If the child must be a single React element, using JSX.Element
is appropriate. It does not, however, permit several children. As a result, we can make the following change:
type Props = { title: string; children?: JSX.Element | JSX.Element[]; };
Using ReactChild
One disadvantage of JSX.Element
is that it does not support strings. As a result, we can include strings in the union type:
type Props = { title: string; children: | JSX.Element | JSX.Element[] | string | string[]; };
However, the example above does not cover number types. So what do we do?
Fortunately, ReactChild
is a standard type that includes React components, strings, and integers. As a result, we can broaden the type for children as follows:
type Props = { title: string; children?: | React.ReactChild | React.ReactChild[]; };
Using ReactNode
React.ReactChild
or React.ReactChild[]
provides the necessary breadth of values but is a little verbose. ReactNode is a more succinct option:
type Props = { title: string; children?: React.ReactNode; };
ReactNode
supports multiple elements, strings, integers, fragments, and portals.
Class
components
What if we want to use a class
component instead of a functional one? Let’s see how we can handle it:
type Props = { title: string, }; export class Page extends React.Component<Props> { render() { return ( <div> <h1>{this.props.title}</h1> {this.props.children} </div> ); } }
The component type, like the FC
type, includes the children
prop by default.
When we hover over the children
prop, we can see what type it has, as seen in the image below:
So, the type of the children
prop in a class
component is ReactNode
.
List of types for React component props
Here’s a list of types you might want to utilize in your React application using Typescript. Some of them are:
- Primitive types, such as string
- Numeric type
- Boolean type
type Props = { // primitive types title: string, score: number, isWinning: boolean }
You can also make an array of a single type by appending the array literal notation ([]
) to the end of the type:
type Props = { title: string[], // an array of string score: number, isWinning: boolean }
You can also use literal values to describe the precise values that the prop can allow.
You must use a single pipe operator (|)
to divide the literals, as seen below:
type Props = { priority: "high" | "normal" | "low", score: 5 | 9 | 10 }
When the value of the priority
or score
prop above does not match any of the literal values, TypeScript will throw a static error.
After that, you can type an object
prop like this:
type Props = { user: { username: string, age: number, isMember: boolean } }
Simply add the array literal notation to the end of the object declaration when you have an array of objects
prop:
type Props = { user: { username: string, age: number, isMember: boolean }[] // right here }
You may need to type function
props since React props can also accept functions like onClick
and onChange
.
You can either input the function’s arguments or get an event
object from the HTML, as seen below:
type Props = { // function that returns nothing onClick: () => void, // function accepts a parameter and has return type onChange: (target: string) => boolean, // function that takes an event handleSubmit: (event: React.FormEvent<HTMLFormElement>) => void }
If you declare an onChange
function in the component’s body, you can instantly examine the function’s parameter and return types, as demonstrated below:
const App = () => { const [message, setMessage] = useState("") const onChange = (e: React.FormEvent<HTMLInputElement>): void => { setMessage(e.currentTarget.value); } }
These are the most frequent React prop types we have in Typescript.
Conclusion
The children prop will become automatically typed if you use function components with the FC
type. The ReactNode
type is often the best choice if you explicitly specify the children
prop.
The post Using the React <code>children</code> prop with TypeScript appeared first on LogRocket Blog.
from LogRocket Blog https://ift.tt/94NvK8L
via Read more