7

Какой тип имеет проп 'children'?

7

У меня есть очень простой функциональный компонент, который выглядит следующим образом:

import * as React from 'react';

export interface AuxProps { 
    children: React.ReactNode
}

const aux = (props: AuxProps) => props.children;

export default aux;

А вот и другой компонент:

import * as React from "react";

export interface LayoutProps { 
   children: React.ReactNode
}

const layout = (props: LayoutProps) => (
    <Aux>
        <div>Toolbar, SideDrawer, Backdrop</div>
        <main>
            {props.children}
        </main>
    </Aux>
);

export default layout;

Я постоянно получаю следующую ошибку:

[ts]
JSX элемент типа 'ReactNode' не является функцией-конструктором для JSX элементов.
Тип 'undefined' не может быть присвоен типу 'ElementClass'. [2605]

Как правильно задать типы в этом случае?

5 ответ(ов)

9

В вашем случае, чтобы указать тип для children в компоненте React, достаточно использовать children: React.ReactNode. Это позволяет вашему компоненту принимать любые валидные элементы React в качестве дочерних компонентов, включая строки, числа, массивы, элементы и даже фрагменты. Пример объявления пропс для компонента может выглядеть так:

import React from 'react';

interface MyComponentProps {
  children: React.ReactNode;
}

const MyComponent: React.FC<MyComponentProps> = ({ children }) => {
  return <div>{children}</div>;
};

Таким образом, React.ReactNode является универсальным типом, который позволяет вам гибко использовать компонент с различными типами дочерних элементов.

1

Чтобы использовать <Aux> в вашем JSX, он должен быть функцией, возвращающей ReactElement<any> | null. Это определение функционального компонента.

Тем не менее, в данный момент он определен как функция, возвращающая React.ReactNode, что является более широким типом. Как говорится в типах React:

type ReactNode = ReactChild | ReactFragment | ReactPortal | boolean | null | undefined;

Убедитесь, что нежелательные типы нейтрализованы, обернув возвращаемое значение в React Fragment (<></>):

const aux: React.FC<AuxProps> = props =>
  <>{props.children}</>;
1

Вам также можно использовать React.PropsWithChildren<P> для определения пропсов компонента с дочерними элементами. Вот пример, как это можно сделать:

type ComponentWithChildProps = React.PropsWithChildren<{ example?: string }>;

В этом примере ComponentWithChildProps будет содержать свойство example, которое является опциональным, а также автоматически включает children, что упрощает работу с дочерними элементами в вашем компоненте.

0

Вы можете использовать ReactChildren и ReactChild:

import React, { ReactChildren, ReactChild } from 'react';

interface AuxProps {
  children: ReactChild | ReactChildren;
}

const Aux = ({ children }: AuxProps) => (<div>{children}</div>);

export default Aux;

Если вам нужно передавать плоские массивы элементов, вы можете изменить интерфейс следующим образом:

interface AuxProps {
  children: ReactChild | ReactChild[] | ReactChildren | ReactChildren[];
}

Таким образом, ваш компонент сможет принимать как одиночные элементы, так и массивы элементов в качестве дочерних элементов.

0

Это сработало для меня:

interface Props {
  children: JSX.Element[] | JSX.Element
}

Правка: Теперь я бы рекомендовал использовать children: React.ReactNode.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь