带有子代的ReactJS TypeScript纯组件

Tom*_*uer 7 typescript reactjs visual-studio-2015 tsx typescript-typings

我有一个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>);
    }
}
Run Code Online (Sandbox Code Playgroud)

我也有一些纯粹的组件,比如这个:

// 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>);
}
Run Code Online (Sandbox Code Playgroud)

我不能为我的生活弄清楚如何制作一个纯粹的容器组件.声明看起来没问题,并且没有显示任何错误:

// 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>);
}
Run Code Online (Sandbox Code Playgroud)

childrenReact.ReactNode因为它就是它的本质React.Props<X>.

使用时,我得到TS2324属性'intrinsicAttributes&{label:string; children:ReactElement | 字符串| 号码| {} | (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>);
}
Run Code Online (Sandbox Code Playgroud)

我不能说下面的片段,因为它会说在外部模块_.tsx中找不到符号'LabelBox'(这是所有这些代码所在的文件).如果我把功能或接口放在第一位并不重要,但无论如何总体上感觉不对.

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>);
}
Run Code Online (Sandbox Code Playgroud)

制作纯粹的TypeScript React组件的正确方法是什么,能够像完整的类组件一样带孩子?这可能吗?我不认为它不应该是,它仍然是一个无状态组件,children并且只是一种特殊的类型props,真正的问题似乎是这里的工具(Visual Studio)没有将TSX内容节点映射到childrenprop.

bas*_*rat 13

制作一个纯粹的TypeScript React组件的正确方法是什么,它能够像完整的类组件一样带孩子

样品:

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

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

当然,如果你愿意的话,你可以自由地做任何事情myAdditionalProp并加入更多的道具PrimitiveProps.只是一定要把它们从allProps传递之前删除.请注意,children作为其一部分传递allProps,因此props.

  • 体验`¯\ _ _(ツ)_ /¯` (6认同)