ReactJS TypeScript чистый компонент с детьми

у меня есть компонент TSX, который является контейнером, обертывающим своих детей так:

import * as React from "react";

interface IProps extends React.Props<Box> {
}

interface IState {
}

export class Box extends React.Component<IProps, IState> {
    render() {
        return (
            <div>
                <h3>Check this out:</h3>
                {this.props.children}
            </div>);
    }
}

у меня также есть некоторые чистые компоненты, такие как этот:

// ReSharper disable once InconsistentNaming - React components must start with a capital letter.
export function LabelTest(props: { label: string }) {
    return (
        <div style={{ display: "flex" }}>
            <label style={{ flex: "1 0 0" }}>{props.label}</label>
            <div style={{ width: "auto" }}>
                This is a pure component.
            </div>
        </div>);
}

Я не могу за жизнь мне выяснить, как сделать чистый контейнер компонент. Объявление выглядит хорошо и не показывает ошибок:

// ReSharper disable once InconsistentNaming - React components must start with a capital letter.
export function LabelBox(props: { label: string, children: React.ReactNode }) {
  return (
    <div style={{ display: "flex" }}>
      <label style={{ flex: "1 0 0" }}>{props.label}</label>
      <div style={{ width: "auto" }}>
        {props.children}
      </div>
    </div>);
}

children is React.ReactNode потому что это то, что в React.Props<X>.

при использовании я получаю собственность TS2324 является отсутствует в типе ' IntrinsicAttributes & { label: string; children: ReactElement | string | number | {} | (Reac....

// ReSharper disable once InconsistentNaming - React components must start with a capital letter.
export function LabelNumberInput(props: { label: string, value: number }) {
  return (
    <LabelBox label={props.label}>
      <input type="number" value={props.value} />
    </LabelBox>);
}

Я не могу сказать что-то вроде фрагмента ниже, потому что он скажет не удается найти символ "LabelBox" во внешнем модуле _.tsx (это файл, в котором весь этот код). Не имеет значения, ставлю ли я функцию или интерфейс первым, но в любом случае это неправильно.

interface ILabelBoxProps extends React.Props<LabelBox> { label: string }
export function LabelBox(props: ILabelBoxProps) {
  return (
    <div style={{ display: "flex" }}>
      <label style={{ flex: "1 0 0" }}>{props.label}</label>
      <div style={{ width: "auto" }}>
        {props.children}
      </div>
    </div>);
}

Как правильно сделать чистый компонент реакции TypeScript, способный принимать детей так же, как компонент полного класса? Возможно ли это? Я не думаю, что это не должно быть, это все еще компонент без гражданства и children просто особый вид props, на самом деле реальная проблема, похоже, заключается в инструменте здесь (Visual Studio), который не сопоставляет узел содержимого TSX с children проп.

2 ответов


каков правильный способ сделать чистый компонент реакции TypeScript, способный принимать детей так же, как компонент полного класса

пример :

interface PrimitiveProps extends React.HTMLProps<HTMLDivElement>{
   myAdditionalProp:any;
};

export const Content = (allProps: PrimitiveProps) => {
    const {myAdditionalProp, ...props} = allProps;
    return (
        <div data-comment="Content" {...props}/>;
    );
};

конечно, вы можете делать все, что угодно с myAdditionalProp и поместите больше реквизита в PrimitiveProps Если вы хотите. Просто не забудьте удалить их из allProps прежде чем передать его мысли. Обратите внимание, что children пройти как его часть allProps и так props.


вот пример:

interface PaginationItemProps extends React.HTMLProps<HTMLDivElement> {
}

const PaginationItem = (props: PaginationItemProps) => {
   return <div>{props.children}</div>;
}

class Pagination extends React.Component<PaginationProps> {
  render() {
    return <div>          
        <PaginationItem>CHILDREN RENDER</PaginationItem>
    </div>
  }
}