【问题标题】:How to pass a functional component as a prop in Typescript and render it?如何在 Typescript 中将功能组件作为 prop 传递并渲染它?
【发布时间】:2023-02-03 13:02:06
【问题描述】:

在下面的代码中,我怎样才能:

  1. 正确输入图标以便 React.createElement 可以创建它?
  2. 如果不使用 React.createElement() 渲染图标?
    function DefaultIcon () {
      return <svg></svg>;
    }
    
    interface ExampleProps {
      icon?: React.ReactElement; // JSX.IntrinsicElements also errors
    }
    
    function Example({ icon = <DefaultIcon /> }: ExampleProps) {
      const Icon = icon;
      return (
        <div>
          {React.createElement(icon)}
          {/* ^Shows Error #1 */}
          {React.createElement(icon as React.ReactElement<any>)}
          {/* ^Shows Error #1 */}
          <Icon />
          {/* ^Shows Error #2 */}
        </div>
      )
    }
    

    错误#1

    No overload matches this call.
    The last overload gave the following error.
    
    Argument of type 'ReactElement<any, string | JSXElementConstructor<any>>' 
    is not assignable to parameter of type 'string | FunctionComponent<any> | 
    ComponentClass<any, any>'.ts(2769)
    

    错误 #2

    JSX element type 'Icon' does not have any construct or call signatures.ts(2604)
    

【问题讨论】:

    标签: reactjs typescript


    【解决方案1】:

    这里的问题是您不能将 jsx 设置为打字稿中道具的默认值,而是尝试修改此代码

    常量图标 = 图标 || DefaultIcon 通过使用此表达式,我们评估如果代码图标未定义,则将使用 DefaultIcon。然后删除道具中的默认值。

    【讨论】:

    • 我确实这样做了,但出于某种原因我仍然收到错误JSX element type 'Icon' does not have any construct or call signatures.ts(2604)...
    【解决方案2】:

    你能试试这个吗?

    function DefaultIcon() {
      return (
        <svg
          width="24"
          height="24"
          viewBox="0 0 24 24"
          fill="none"
          xmlns="http://www.w3.org/2000/svg"
        >
          <path
            d="M4.57574 12.5757C4.34142 12.8101 4.34142 13.1899 4.57574 13.4243C4.81005 13.6586 5.18995 13.6586 5.42426 13.4243L4.57574 12.5757ZM15.6 3C15.6 2.66863 15.3314 2.4 15 2.4L9.6 2.4C9.26863 2.4 9 2.66863 9 3C9 3.33137 9.26863 3.6 9.6 3.6H14.4V8.4C14.4 8.73137 14.6686 9 15 9C15.3314 9 15.6 8.73137 15.6 8.4L15.6 3ZM5.42426 13.4243L15.4243 3.42426L14.5757 2.57574L4.57574 12.5757L5.42426 13.4243Z"
            fill="#404040"
          />
        </svg>
      );
    }
    
    interface ExampleProps {
      // eslint-disable-next-line react/require-default-props
      icon?: React.ReactNode;
    }
    
    function Example({ icon = <DefaultIcon /> }: ExampleProps) {
      return <div>{icon}</div>;
    }
    
    export default Example;
    

    【讨论】:

    • 哦,伙计,我太蠢了。是的,行得通。如果您熟悉React.createElement(),您是否介意也分享如何使它工作?
    猜你喜欢
    • 2019-05-11
    • 2022-01-06
    • 1970-01-01
    • 1970-01-01
    • 2020-03-14
    • 1970-01-01
    • 1970-01-01
    • 2020-08-05
    • 1970-01-01
    相关资源
    最近更新 更多