【问题标题】:Trying to dynamically render JSX tag尝试动态呈现 JSX 标签
【发布时间】:2020-08-12 10:40:35
【问题描述】:

我正在创建一个<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>)
  }

}

【问题讨论】:

标签: javascript reactjs typescript jsx


【解决方案1】:

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

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

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

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

当然,您需要使用 React.HTMLProps&lt;T&gt;. 在 Text 属性中添加正确的类型。像这样:

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

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

编辑:如果您要将HTMLProps 与您自己的道具(例如IProps)结合起来,那么您将编写IProps &amp; React.HTMLProps&lt;HTMLHeadingElement | HTMLParagraphElement&gt;

此时,在 this.props 中,您将拥有 (p|h) 道具和在 IProps 中定义的道具。

那么,此时,由于ph 元素不应该使用来自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}</>;

【讨论】:

  • 嘿@Jolly 给定&lt;React.HTMLProps&lt;HTMLHeadingElement | HTMLParagraphElement&gt;,你如何添加IProps?
  • 什么是IProps?基础道具你的App?您可以只使用 &amp; 运算符来“合并”TypeScript 接口。如果你写 IProps &amp; React.HTMLProps&lt;HTMLHeadingElement | HTMLParagraphElement&gt;,你的 props 将期望 IPropshp 元素的基本 props 中的任何内容。然后,请注意,在将道具传递给createElement 时,您可能需要删除来自IProps 的道具。我将使用这条新信息编辑答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-31
  • 2016-04-19
  • 2017-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多