ReactJS TypeScript 纯子组件

Posted

技术标签:

【中文标题】ReactJS TypeScript 纯子组件【英文标题】:ReactJS TypeScript pure component with children 【发布时间】:2016-10-15 18:56:36 【问题描述】:

我有一个 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>);

childrenReact.ReactNode,因为这就是 React.Props&lt;X&gt; 中的内容。

使用时我得到 TS2324 属性 'children' is missing in type 'IntrinsicAttributes & label: string;孩子:反应元素 |字符串 |号码 | | (反应...

// 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>);

我不能说像下面的 sn-p 这样的东西,因为它会说 Cannot find symbol 'LabelBox' in external module _.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 React 组件能够像完整类组件一样获取子组件的正确方法是什么?这可能吗?我认为不应该,它仍然是一个无状态组件,children 只是一种特殊的props,真正的问题似乎是这里的工具(Visual Studio)没有映射 TSX children 属性的内容节点。

【问题讨论】:

【参考方案1】:

什么是使纯 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/>;
    );
;

当然,您可以随意使用myAdditionalProp 做任何事情,如果您愿意,可以在PrimitiveProps 中添加更多道具。请确保在通过之前将它们从allProps 中删除。请注意,children 作为allProps 的一部分传递,因此是props

【讨论】:

你是怎么想出来的?有没有我应该在问问题之前看的地方,但我错过了?我没想到的 Google 查询? 体验¯\_(ツ)_/¯? 感谢您当时没有保密,您帮了我很多忙! :)【参考方案2】:

这是完整的例子:

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>
  

【讨论】:

以上是关于ReactJS TypeScript 纯子组件的主要内容,如果未能解决你的问题,请参考以下文章

Typescript:如何从 react-bootstrap 导入特定组件

当 ReactJS 遇到 TypeScript

Typescript reactjs无法将道具传播到输入标签

来自配置的 React 和 Typescript 动态组件

将 onclick 函数作为参数传递给 react/typescript 中的另一个组件

来做操吧!深入 TypeScript 高级类型和类型体操