Search code examples
javascriptreactjsrecursive-component

how to render component that its inside value of object key using recursive component pattern in react?


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?


Solution

  • 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>
      );
    }