将 React.FunctionComponent<React.SVGProps<SVGSVGElement>> 作为道具发送到另一个组件

Posted

技术标签:

【中文标题】将 React.FunctionComponent<React.SVGProps<SVGSVGElement>> 作为道具发送到另一个组件【英文标题】:Sending a React.FunctionComponent<React.SVGProps<SVGSVGElement>> as a prop to another component 【发布时间】:2020-07-28 10:56:57 【问题描述】:

我正在尝试从 SVG 导入 React functionComponent,然后将其作为 prop 发送到另一个组件以呈现该 svg。使用下面的设置,这编译得很好,但最终在尝试在浏览器中渲染 svg 时崩溃:

错误:对象作为 React 子对象无效(找到:带有键 $$typeof,render 的对象)。如果您打算渲染一组子项,请改用数组。

下面的类被简化了。但我想做的事情的要点是:

在overlay.tsx中:

import  ReactComponent as icon  from "/icon.svg";
import CustomItem from "/customItem";

const Overlay: React.FC<OverlayProps> = () => 

    return (
        <div>
            <CustomItem icon=icon/>
        </div>
    );
    export default Overlay;

在 customItem.tsx 中:

import React from "react";

export interface CustomItemProps 
    icon: React.FunctionComponent<React.SVGProps<SVGSVGElement>>;


const CustomItem: React.FC<CustomItemProps> = (icon) => 

    return (
        <div>
            icon
        </div>
    );
;

export default ApplicationsDropdownItem;

我认为我的问题与 icon 的语法有关,但我终其一生都无法找出我应该使用什么。

【问题讨论】:

将 svg 位置作为字符串导入并用 绘制它确实有效,但这消除了使用 svg 作为组件所带来的所有 css 可能性。 【参考方案1】:

我认为你应该使用&lt;Icon /&gt; 而不是icon,因为它是一个组件。

【讨论】:

那行不通。它不知道从哪里获取所述组件 @Excludos 从字面上分配const Icon = props.icon 并将其用作组件。它已经是 FunctionComponent 类型了,你只需要这样使用它。【参考方案2】:

回答

您要导入的图标是一个组件,因此必须调用它来渲染 JSX。

&lt;Icon ...props/&gt;(正确)或Icon(props)(不推荐)

既然它是一个组件,你也应该把它命名为Icon而不是icon

看看 this blog post 解释 SVGR。

TL;DR - 渲染组件的最佳方法

A.使用组件语法 &lt;MyComponent/&gt; 而不是 MyComponent() 在您的渲染方法中调用组件。

B.将您的组件实例化为变量,并将其传递给您的渲染方法的 JSX 块。

更多信息

@DustInCompetent 揭示了在 JSX 块中将组件作为函数调用的问题。

正如here 和here 解释的那样,这将导致反应未注册组件挂钩并导致状态和其他问题。

如果您正在实现高级组件 (HOC),则不应调用组件 within the render method(功能组件中的返回语句),因为这会导致组件出现类似注册问题。

【讨论】:

我读到 fnComp(props) 表单不鼓励使用,因为它会混淆事件传播和 React 开发工具或其他东西 我也认为它的风格丑陋和混乱,我很少看到它被使用;不过,这是可能的。我将更新我的示例以澄清这一点。如果您找到/回忆起提到这一点的资源,最好在此处添加。 我想我找到了:reactjs.org/docs/…。这是关于 HOC,但同样适用于调用在每次渲染时返回新组件树的函数。 这很有趣。我理解这意味着组件应该在组件的渲染/返回语句之外实例化。不一定在 JSX 块中不应该使用函数语法。但不确定。 刚刚用谷歌搜索并找到了这个SO answer,这让我找到了this article,它解释了当组件在 JSX 中被调用为函数时,React 无法注册组件的钩子。【参考方案3】:
import React from "react";
import  ReactComponent as SampleIcon  from "/sample_icon.svg";

export interface CustomItemProps 
  Icon: React.FunctionComponent<React.SVGProps<SVGSVGElement>>;


const CustomItem: React.FC<CustomItemProps> = (props) => 
  const Temp = props.Icon as React.FunctionComponent<React.SVGProps<SVGSVGElement>>;
  return (
    <div>
      <Temp/>
    </div>
  );
;

<CustomItem Icon=SampleIcon/>

【讨论】:

能否请您用一些描述详细说明您的答案,以便它带来更多上下文。纯代码的答案很难阅读和理解。谢谢

以上是关于将 React.FunctionComponent<React.SVGProps<SVGSVGElement>> 作为道具发送到另一个组件的主要内容,如果未能解决你的问题,请参考以下文章

useEffect 用于设置输入值时抛出错误

TypeScript 3:JSX 元素类型“组件”没有任何构造或调用签名。 [2604]

反应“错误:超过最大更新深度。”带有功能组件和钩子

这是避免“你在提前返回后不小心调用了 React Hook 吗?”的安全方法吗?

无法输入 <Formik> 字段

本机基础文本仅在某些屏幕上显示大写