将 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】:我认为你应该使用<Icon />
而不是icon
,因为它是一个组件。
【讨论】:
那行不通。它不知道从哪里获取所述组件 @Excludos 从字面上分配const Icon = props.icon
并将其用作组件。它已经是 FunctionComponent 类型了,你只需要这样使用它。【参考方案2】:
回答
您要导入的图标是一个组件,因此必须调用它来渲染 JSX。
<Icon ...props/>
(正确)或Icon(props)
(不推荐)
既然它是一个组件,你也应该把它命名为Icon
而不是icon
。
看看 this blog post 解释 SVGR。
TL;DR - 渲染组件的最佳方法
A.使用组件语法 <MyComponent/>
而不是 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>> 作为道具发送到另一个组件的主要内容,如果未能解决你的问题,请参考以下文章
TypeScript 3:JSX 元素类型“组件”没有任何构造或调用签名。 [2604]