-1

I have these arrays of objects, So I try to render each value with its key using the recursive component pattern.

file: App.jsx:

import RecursiveComponent from "./components/RecursiveComponent.jsx";
import { ReactComponent as ReactIcon } from "./assets/react.svg";

const container = [
  {
    title: "title one",
    sections: [
      {
        title: "title tow",
        cards: [
          {
            name: "Excellent ",
            icon: <ReactIcon />,
          }
        ],
      },
    ],
  },
];

export default function App() {
  return (
    <div>
      <RecursiveComponent data={container} />
    </div>
  );
}

I decided to write this code inside RecursiveComponent.jsx:

import React from "react";

export default function RecursiveComponent({ data }) {
  if (typeof data !== "object") {
    return <p> value : {data}</p>;
  }

  const pairs = Object.entries(data);

  return (
    <div>
      <hr />
      {pairs.map(([key, value], index) => {
        return (
          <div style={{ display: "flex" }} key={index}>
            <h4>key: {key} </h4>
            <RecursiveComponent data={value} />
          </div>
        );
      })}
    </div>
  );
}

when they try to run icon: <ReactIcon />, it gives me this error:

Uncaught TypeError: Cannot convert undefined or null to object

and this warning:

Functions are not valid as a React child. This may happen if you return a Component instead of <Component /> from render. Or maybe you meant to call this function rather than return it

so right now, how can I render <ReactIcon /> in this scenario?

Yahia
  • 19
  • 5
  • There is zero reason to do this in the code you've shown: there is seldom if ever a reason to store a JSX tag in component state or even (as you've done here) a module-level constant. Just store the *component definition* `icon: ReactIcon,` and have the code that reads the data render the actual JSX tag `const Icon = record.icon; return ;` – Jared Smith Aug 18 '23 at 13:58
  • we face a situation with an info Modal with static data inside it @JaredSmith, so we decide to have an array of objects and insert all data inside it with their icons. so that way, we can render all data with the recursive component pattern because it's clean and nice – Yahia Aug 19 '23 at 07:15

1 Answers1

1

Implement a base case in your recursive component for handling React elements.

Check if a value is a React element using React.isValidElement function.

export default function RecursiveComponent({ data }) {
  if (typeof data !== "object" || React.isValidElement(data)) {
    return <p> value : {data}</p>;
  }

  const pairs = Object.entries(data);

  return (
    <div>
      <hr />
      {pairs.map(([key, value], index) => {
        return (
          <div style={{ display: "flex" }} key={index}>
            <h4>key: {key} </h4>
            <RecursiveComponent data={value} />
          </div>
        );
      })}
    </div>
  );
}
Oluwafemi Sule
  • 36,144
  • 1
  • 56
  • 81