首页 > 解决方案 > 尝试动态呈现 JSX 标签

问题描述

我正在创建一个<Text />组件,以便我可以轻松控制 Text 在我的应用程序中的使用方式。我希望能够为<Text />组件选择一个标签,具体取决于它是什么(例如<p>,对于正文文本,<h1>对于标题)。

但是,我被困在第一步。当我尝试使用函数返回标签时,出现以下错误:

Type '{ children: string; }' has no properties in common with type 'IntrinsicAttributes'.ts(2559)

这是我的组件:

import * as React from 'react'

export class Text extends React.Component {

  constructor(props) {
    super(props)
  }

  getMarkup() {
    return 'h1'
  }

  render() {
    const CustomTag = this.getMarkup()
    return (<CustomTag>Hello</CustomTag>)
  }

}

标签: javascriptreactjstypescriptjsx

解决方案


由于您要将标签视为字符串,因此可以使用React.createElement. 里面render,写如下:

const element = React.createElement(this.getMarkup(), {}, 'Hello');
return <>{element}</>;

基本上,createElement期望元素的类型为字符串,因此您可以传递 ,'h1'而不会让 TypeScript 打扰您。
此外,您可以看到我传递了一个空数组作为第二个参数:在那里您可以传递任何道具,例如style, onClick, ... 通常,在这种情况下,您可以编写如下:

const element = React.createElement(this.getMarkup(), {{...this.props}}, 'Hello');

但当然,您需要使用..在Text道具中添加正确的类型,如下所示:React.HTMLProps<T>

class App extends React.Component<React.HTMLProps<HTMLHeadingElement | HTMLParagraphElement>, IState> {`

在这种情况下,我只考虑handp元素。

编辑:如果您要将HTMLProps与您自己的道具结合起来,例如IProps,那么您将编写IProps & React.HTMLProps<HTMLHeadingElement | HTMLParagraphElement>.

此时,this.props您将在内部拥有 ( p| h) 道具和在IProps.

然后,在这一点上,由于pand helement 不应该接受来自 的道具IProps,你应该重写createElement如下:

// Assuming you have this IProps
interface IProps {
  tag: string;
  myProp: number;
}

// Inside render
const { tag, myProp, ...otherProps } = {...this.props};
const element = React.createElement(this.getMarkup(), otherProps, 'Hello');
return <>{element}</>;

推荐阅读