React native typescript children

TypeScript and Children

TypeScript and Children

What happens when we pass in children in React? Children is a special prop that allows us to pass in any type of element. It could be a number, a string, a boolean, an array of elements or even another component. So how can we check the types?

Of course we could define it as any which is basically the same as just not having type checking which defeats the whole purpose of using Typescript.

There are a couple of types we could choose from:

JSX.Element

Children must be a single JSX element. Doesn’t allow multiple children, or strings etc.

interface ButtonProps  children: JSX.Element>const Button = ( children >: ButtonProps) => button>children>button> export function Card()  return ( Button> span>Click mespan> Button> )>

JSX.Element

Allows multiple JSX elements but no strings, numbers etc

interface ButtonProps  children: JSX.Element[]>const Button = ( children >: ButtonProps) => button>children>button> export default function Card()  return ( Button> span>click mespan> i>svg iconi> Button> )>

JSX.Element | JSX.Element

Allows single or multiple JSX elements but no strings, numbers etc

interface ButtonProps  children: JSX.Element | JSX.Element[]>const Button = ( children >: ButtonProps) => button>children>button> export function Card()  return ( Button> span>click mespan> Button> )>export function Card2()  return ( Button> span>click mespan> i>svg iconi> Button> )>

React.ReactChild

Allows one React element, string or number

interface ButtonProps  children: React.ReactChild>const Button = ( children >: ButtonProps) => button>children>button> export default function Card()  return Button>click meButton>>

React.ReactChild

Allows multiple React elements, strings or numbers

interface ButtonProps  children: React.ReactChild>const Button = ( children >: ButtonProps) => button>children>button> export default function Card()  return ( Button> click me i>svg iconi> Button> )>

React.ReactChild | React.ReactChild

Allows single or multiple React elements, strings or numbers

interface ButtonProps  children: React.ReactChild>const Button = ( children >: ButtonProps) => button>children>button> export function Card()  return Button>click meButton>> export function Card2()  return ( Button> click me i>svg iconi> Button> )>

React.ReactNode

Allows multiple children, strings, numbers, fragments, portals. We could use the above example but it is a little verbose and ReactNode covers a little more.

interface ButtonProps  children: React.ReactNode>const Button = ( children >: ButtonProps) => button>children>button> export default function Card()  return ( Button> click me i>svg iconi> Button> )>

Conclusion

And that’s it, you now have no excuses for adding type checking for your children.

Источник

Using the React children prop with TypeScript

Using the React children prop with TypeScript

Properly typing the children prop in React can pose some difficulty at first. If you try typing them as specific JSX types, you may run into issues rendering the child components. There’s also the problem with the paradox of choice, as there are multiple available options to type the children prop. This may lead to decision fatigue.

In this article, I’ll share my recommended solutions to this, based on experience. For completeness, I’ll also share some other, arguably relevant approaches.

Children in JSX

When you write a JSX expression with opening and closing tags, the content passed between them is referred to as their “child”.

Children passed between the opening and closing tag of your JSX expression

Consider the following contrived example:

 Hey, I represent the JSX children! 

In this example, the literal string Hey, I represent the JSX children! refers to the child rendered within Border .

Conversely, to gain access to the content passed between JSX closing and opening tags, React passes these in a special prop: props.children

For example, Border could receive the children prop as follows:

Border accepts the children prop, then renders the children within a div with a border style of 1px solid red .

This is the basic usage of the children prop, i.e., to receive and manipulate the content passed within the opening and closing tags of a JSX expression.

Supported children types

Strictly speaking, there’s a handful of supported content types that can go within the opening and closing tags of your JSX expression. Below are some of the most used ones:

Strings

Literal strings are valid children types, as shown below:

 This is a valid child string 

Note that in YourComponent , props.children will simply be the string This is a valid child string .

JSX

You can equally pass other JSX elements as valid children. This is usually helpful when composing different nested components. Below’s an example:

It is also completely acceptable to mix children types, as shown below:

 I am a valid string child   

JavaScript expressions

Expressions are equally valid children types, as shown below:

Remember that expressions in JSX are written in curly braces.

Functions

Functions are equally valid children types as shown below:

As you can see, the children prop can be represented by quite a wide range of data types! Your first inclination might be to type these out manually, like so:

type Props = < children: string | JSX.Element | JSX.Element[] | () =>JSX.Element > const YourComponent = ( : Props) =>

This might seem like a good idea, but it doesn’t fully represent the children prop. What about fragments, portals, and ignored render values, such as undefined , null , true , or false ?

Over 200k developers use LogRocket to create better digital experiences

Learn more →

A full representation may look something like this:

type ReactText = string | number; type ReactChild = ReactElement | ReactText; interface ReactNodeArray extends Array <> type ReactFragment = <> | ReactNodeArray; type ReactNode = ReactChild | ReactFragment | ReactPortal | boolean | null | undefined; type Props = < children: ReactNode >// source: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/d076add9f29db350a19bd94c37b197729cc02f87/types/react/index.d.ts

See the extended types for ReactPortal and ReactElement. Do they look complex? There’s a good chance they do.

The point I’m trying to make is, in practice, you don’t want to type the children prop manually. Instead, I suggest using the officially supported types discussed below.

Using the PropsWithChildren type

The React.PropsWithChildren type takes your component prop and returns a union type with the children prop appropriately typed. No extra work from you needed.

In practice, here’s the definition for the PropsWithChildren type:

type PropsWithChildren = P & < children?: ReactNode >;

How the propsWithChildren type works

Assuming you had a component Foo with props FooProps :

type FooProps = < name: 'foo' >export const Foo = (props: FooProps) =>

You can go ahead and introduce the children prop as follows:

import < PropsWithChildren >from ‘react’ type FooProps = < name: 'foo' >export const Foo = (props: PropsWithChildren) =>

When you pass PropsWithChildren to your component prop FooProps , you get the children prop internally typed.

In most cases, this is the recommended way to go about typing the children prop because it requires less boilerplate and the children prop is implicitly typed.

Explicitly using the ReactNode type

In cases where you must explicitly type the children prop, you can go ahead and use the ReactNode type.

Remember the definition for the PropsWithChildren type:

type PropsWithChildren = P & < children?: ReactNode >;

The propsWithChildren type leverages the reactNode type

Instead of relying on PropsWithChildren , you can also type the children prop directly:

import < ReactNode >from ‘react’ type FooProps = < name: 'foo' // look here 👇 children: ReactNode >export const Foo = (props: FooProps) =>

Using the FunctionComponent (or FC ) type

The FunctionComponent generic interface may also be used to appropriately type the children prop. Internally, this interface relies on PropsWithChildren .

import < FunctionComponent >from ‘react’ type FooProps = < name: 'foo' >export const Foo: FunctionComponent = (props) =>

Note that the FC type is an alias for FunctionComponent for ease. Their usages are similar, as shown below:

import < FC >from ‘react’ type FooProps = < name: 'foo' >export const Foo: FC = (props) =>

Using the Component type for class components

Most modern React codebases no longer use class components, except in specific use cases.
If you find yourself needing to type the children prop in a class component, leverage the Component prop, as shown below:

import < Component >from 'react' type FooProps = < name: 'foo' >class Foo extends Component  < render() < return this.props.children >>

Similar to the FunctionComponent interface and its FC alias, the Component type automatically includes the children prop.

Conclusion

Where possible, use the PropsWithChildren type, but don’t be afraid to type the children prop directly as well, whether that’s in a class or functional component.

Get set up with LogRocket’s modern React error tracking in minutes:

  1. Visit https://logrocket.com/signup/ to get an app ID.
  2. Install LogRocket via NPM or script tag. LogRocket.init() must be called client-side, not server-side.
$ npm i --save logrocket 

// Code:

import LogRocket from 'logrocket';
LogRocket.init('app/id');
Add to your HTML:

script src="https://cdn.lr-ingest.com/LogRocket.min.js"> /script>
script>window.LogRocket && window.LogRocket.init('app/id');script>

Источник

React Children with TypeScript

The React children prop allows components to be composed together and is a key concept for building reusable components. Visually, we can think of it as a hole in the component where the consumer controls what is rendered. This post covers different approaches to strongly-typing this powerful and flexible prop with TypeScript.

React Children with TypeScript

Using the FC type

There is a standard React type, FC , that we can use on arrow function components. FC stands for Function Component, and it aliases a type called FunctionComponent .

type Props =  title: string, >; const Page: React.FCProps> = (< title, children, >) => ( div> h1>title>h1> children> div> );

FC is a generic type that takes in the specific type for all the component props. In the example above, we passed in a Props type alias containing a title prop. Alternatively, an interface could be used to define Props .

Notice that children isn’t defined in Props . Instead, it is already defined in the FC type. This is nice if you know this fact, but it might be a bit confusing if you don’t.

Explicitly defining the children prop type

If we explicitly define the children prop type, we have several different options for its type.

Let’s go through them one by one …

Using JSX.Element

Let’s try JSX.Element for starters:

type Props =  title: string, children: JSX.Element,>; const Page = ( title, children >: Props) => ( div> h1>title>h1> children> div> );

children is required at the moment. If we want to make this optional for the consumer of the component, we put a question mark( ? ) before the type annotation:

type Props =  title: string; children?: JSX.Element;>;

JSX.Element is good if the child is required to be a single React element. However, it doesn’t allow multiple children. So, we could make the following adjustment:

type Props =  title: string; children?: JSX.Element | JSX.Element[];>;

Using ReactChild

A downside of JSX.Element is that it doesn’t allow strings. So, we could add strings to the union type:

type Props =  title: string; children: | JSX.Element | JSX.Element[] | string | string[];>;

… this is getting out of hand!

Fortunately, there is a standard type called ReactChild that includes React elements, strings and numbers. So, we could widen the type for children as follows:

type Props =  title: string; children?: | React.ReactChild | React.ReactChild[];>;

Using ReactNode

React.ReactChild | React.ReactChild[] gives the breadth of values we need, but is a little verbose. ReactNode is a more terse option:

type Props =  title: string; children?: React.ReactNode;>;

ReactNode allows multiple elements, strings, numbers, fragments, portals, …

The FC generic type uses ReactNode under the hood as well.

Class components

What if we are using a class component? Let’s explore this:

type Props =  title: string, >; export class Page extends React.ComponentProps>  render()  return ( div> h1>this.props.title>h1> this.props.children> div> ); > >

Like FC , the Component type automatically includes the children prop.

If we hover over the children prop, we discover the type it has been given:

Class children

So, the type of the children prop in a class component is ReactNode as well.

Wrap up

If we are using function components with the FC type, the children prop is already typed. If we explicitly type the children prop, the ReactNode is generally the best choice.

Did you find this post useful?

If you to learn more about using TypeScript with React, you may find my course useful:

Источник

Читайте также:  Тинькофф инвестиции api php
Оцените статью