Skip to content

How to dynamically map an array within another array in React?

I’m building a table of content using React. I’m calling my database to fetch each array(which are always different depending on query). I would like to render each child array when I click on the parent item. Here’s conceptually what I want:

<ul id="parent" onClick={renderChildArray()}>

       <li id="child" onClick={renderChild2Array()}>
        {child2array}   
       <li>

</ul>

Here’s my code:

tableOfContent = () => {
        const { TOC, headers2 } = this.state;

        return (
            <div>
                {TOC.map((header) => (
                    <ul
                        key={header.index}
                        onClick={() =>
                            this.handleHeaderClick(
                                header.level,
                                header.treepath,
                                header.containsLaw,
                                header.sections,
                                header.ObjectId,
                            )
                        }
                        className="TOC TOCsection"
                    >
                        {header._id}
                        {headers2.map((i, index) => (
                            <li
                                className="TOCsection"
                                style={{ listStyle: "none" }}
                                key={index}
                            >
                                {i._id}
                            </li>
                        ))}
                    </ul>
                ))}
            </div>
        );
    };

Right now, when I click on the parent the child appears on each parent key item. I want the child array to render under the parent that I clicked only. How to do that?

Answer

You can save the clicked parent’s index in the state. And when rendering child items check if the current parentIndex === saveIndex and then render the child. I can write the pseudocode for this as I don’t have a working version of your problem.

tableOfContent = () => {
        const { TOC, headers2 } = this.state;

        return (
            <div>
                {TOC.map((header, parentIndex) => (
                    <ul
                        key={header.index}
                        onClick={() =>
                            this.handleHeaderClick(
                                header.level,
                                header.treepath,
                                header.containsLaw,
                                header.sections,
                                header.ObjectId,
                            );
                            saveTheIndex(parentIndex); // This method should save parentIndex in the state. I am assuming the state variable is named 'clickedParentIndex'.
                        }
                        className="TOC TOCsection"
                    >
                        {header._id}
                        { clickedParentIndex === parentIndex && headers2.map((i, index) => (
                            <li
                                className="TOCsection"
                                style={{ listStyle: "none" }}
                                key={index}
                            >
                                {i._id}
                            </li>
                        ))}
                    </ul>
                ))}
            </div>
        );
    };