Nipun Ravisara
Nipun Ravisara

Reputation: 4471

How to create a nested accordion in reactjs

Intro - I'm trying to show JSON data in a Accordion. So I used react-sanfona (github) to build that. I'm trying to call getComponent function recursively so that I can check if it is an array or object if it is array I'm calling same function. better show you the pogress so far.

Problem - I'm getting [object Object] at the second level even I call the getComponent recursively

Edit on codesandbox

Upvotes: 0

Views: 3048

Answers (3)

Rahul Soni
Rahul Soni

Reputation: 105

This is working code, which might help you Here, initially root folder will be hiding all children once click on root -> its direct children will be displayed/hidden and so on

//explorer is the json coming from parent component
import React, { useState } from "react";

function Accodian({ explorer }) {
  const [expand, setExpand] = useState(false);

  if (explorer.children) {
    return (
      <div>
        {/* {explorer.children ? ( */}
        <>
          <div onClick={() => setExpand((prevState) => !prevState)}>
            {explorer.name}
          </div>
          {expand ? (
            <>
              {explorer.children.map((child) => {
                // return <div key={child.name} style = {{paddingLeft: '20px'}}>{child.name}</div>;
                return <Accodian explorer={child} key={child.name} />;
              })}
            </>
          ) : null}
        </>
        {/* ) : null} */}
      </div>
    );
  } else {
    return <div style={{ paddingLeft: "20px" }}>{explorer.name}</div>;
  }
}

export default Accodian;

Check this sandbox : https://codesandbox.io/s/js-recursion-accordian-v03y5q?file=/src/components/Accordian.js:0-823/

Upvotes: 0

Apostolos
Apostolos

Reputation: 10498

Problem was that you didn't return anything when dealing with object

So this part

  Object.keys(record).map((key, index) => {
    console.log(44);
    return (
      <AccordionItem className="ml-5" title={`1 - ${index}`} expanded>
        {getComponent(record[key])}
      </AccordionItem>
    );
  });

should be

  return Object.keys(record).map((key, index) => {
    console.log(44);
    return (
      <AccordionItem className="ml-5" title={`1 - ${index}`} expanded>
        {getComponent(record[key])}
      </AccordionItem>
    );
  });

I added a default expanded property and now it displays all data.

Check this sandbox

Upvotes: 1

Raphael Escrig
Raphael Escrig

Reputation: 146

Hy, I don't know exactly what you want to display but here is a version working.

import { Accordion, AccordionItem } from "react-sanfona";
import "./styles.css";

const datalist = [
  {
    id: 3423235234,
    name: "John",
    address: [
      {
        first: "city1",
        second: "city2"
      }
    ]
  }
];

export default function App() {
  function getComponent(record) {
    if (Array.isArray(record)) {
      return record.map((b, index) => (
        <AccordionItem className="ml-5" title={`${index}`} key={index}>
          {getComponent(b)}
        </AccordionItem>
      ));
    }
    if (typeof record === "object") {
      return (
        <div>
          {Object.keys(record).map((key, index) => {
            return (
              <AccordionItem
                className="ml-5"
                title={`1 - ${index}`}
                expanded
                key={index}
              >
                {getComponent(record[key])}
              </AccordionItem>
            );
          })}
        </div>
      );
    }
    if (typeof record === "string" || typeof record === "number") {
      console.log("string or number: ", record);
      return <AccordionItem className="ml-5" title={`2 - ${record}`} />;
    }

    return (
      <AccordionItem className="ml-5" title={`3 - ${record.toString()}`} />
    );
  }

  return (
    <div className="App">
      <div className="px-7">
        <Accordion>{getComponent(datalist)}</Accordion>
      </div>
    </div>
  );
}

The package you're using raise many errors in the console (with no configuration). Did you check the material ui's accordions ? https://material-ui.com/components/accordion/

Upvotes: 1

Related Questions