Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sending a React.FunctionComponent<React.SVGProps<SVGSVGElement>> as a prop to another component

I'm attempting to import a React functionComponent from an SVG and then send that to another component as a prop to render that svg. With the setup below, this compiles fine, but eventually crashes when trying to render the svg in browser with:

Error: Objects are not valid as a React child (found: object with keys {$$typeof, render}). If you meant to render a collection of children, use an array instead.

Classes below are simplified. But the gist of what I'm trying to do is:

In 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;
}

and in 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;

I assume my problem is somewhere around the syntax of {icon}, but I can not for the life of me find out what I'm suppose to use instead.

like image 821
Excludos Avatar asked Sep 01 '25 04:09

Excludos


1 Answers

Answer

The icon you are importing is a component, therefore it must be called to render the JSX.

<Icon {...props}/> (correct) or {Icon(props)} (not recomended)

Since it is a component, you should also name it Icon and not icon.

Take a look at this blog post that explains SVGR.

TL;DR - Best approach for rendering components

A. Call the component in your render method with component syntax <MyComponent/> not MyComponent().

B. Instantiate your component as a variable, and pass that to your render method's JSX block.

More info

@DustInCompetent brought to light the issue of calling a component as a function inside a JSX block.

As explained here and here, that will lead to react not registering a components hooks and lead to state and other problems.

If you are implementing a High Level Component (HOC), then you should not call a component within the render method (return statement in functional components), as this leads to problems for similar registration issues of the component.

like image 156
ryanjdillon Avatar answered Sep 02 '25 19:09

ryanjdillon