1

(I apologize for the ugly code in advance -- currently refactoring)

I'm making a Table of content where the nested content appear when I click on its parent component.

For my logic, I need to pass the value of the list key to its children but I keep receiving an undefined error or nothing at all. I tried to pass the value like this: key={node2.objectId} and keyId={node2.objectId}

I read the specifications on how to pass the key value as a prop here and here

Yet, nothing works.

Here's my code:

import React from "react";

const TocContent = (props) => {
    return (
        <div className="">
            {props.TOC.map((header) => (
                <ul
                    key={header.objectId}
                    onMouseDown={(e) => e.stopPropagation()}
                    onClick={(e) =>
                        props.handleHeaderClick(
                            header.level,
                            header.treepath,
                            header.containsLaw,
                            header.sections,
                            header.secNum,
                            header.objectId,
                            header.id,
                            e.stopPropagation(),
                        )
                    }
                    className="TOC TOCsection"
                >
                    {header._id}

                    {props.headerIndex === header.objectId
                        ? props.headers2.map((node2) => (
                                <HeaderList
                                    key={node2.objectId}
                                    header={node2}
                                    props={props}
                                    keyId={node2.objectId}
                                >
                                            {console.log(props.keyId)}
                          //--problem is here-- {props.headerIndex2 === props.keyId
                                        ? props.headers3.map((node3) => (
                                                <HeaderList
                                                    key={node3.objectId}
                                                    header={node3}
                                                    props={props}
                                                >
                                                    {props.headerIndex3 === node3.objectId
                                                        ? props.headers4.map((node4) => (
                                                                <HeaderList
                                                                    header={node4}
                                                                    key={node4.objectId}
                                                                    props={props}
                                                                />
                                                          ))
                                                        : null}
                                                </HeaderList>
                                          ))
                                        : null}
                                </HeaderList>
                          ))
                        : null}
                </ul>
            ))}
        </div>
    );
};

const HeaderList = ({ header, props }) => {
    return (
        <ul
            onMouseDown={(e) => e.stopPropagation()}
            onClick={(e) =>
                props.handleHeaderClick(
                    header.level,
                    header.treepath,
                    header.containsLaw,
                    header.sections,
                    header.secNum,
                    header.objectId,
                    header.id,
                    e.stopPropagation(),
                )
            }
        >
            {header._id}
        </ul>
    );
};

export default TocContent;
xom9ikk
  • 2,159
  • 5
  • 20
  • 27
Dom355
  • 171
  • 2
  • 15
  • 1
    You are passing down the entire node as the `header` prop. Could you just not use `header.objectId` in `HeaderList` to get the value of your `key` prop? – Tholle Dec 27 '20 at 00:59
  • @Tholle I use the header.objectId to save the headerIndex of the component. I use the value in my logic : props.headerIndex === header.objectId. – Dom355 Dec 27 '20 at 01:22
  • 1
    Yes, but the issue is that you can't read the `key` prop in the `HeaderList` component, right? Why not just use the value of `header.objectId` instead, since it's the same thing? – Tholle Dec 27 '20 at 01:26
  • I get your point. When I console.log(header.objectId), I get the entire object (8 "objectId" instead of 1). In the first few lines of my code, it works because each
      has one objectId. The gets 8 objectId. I guess my problem lies there...
    – Dom355 Dec 27 '20 at 02:16

1 Answers1

0

I finally resorted to change the structure a bit. Instead of the code above, I opted to render the HeaderList component directly in its own component (as a child of itself). This way, I'm able to read header.objectId and make the code shorter.

Here's the new code:

import React from "react";

const TocContent = (props) => {
    return (
        <div className="">
            {props.TOC.map((header) => (
                <HeaderList key={header.objectId} header={header} props={props} />
            ))}
        </div>
    );
};

const HeaderList = ({ header, props }) => {
    return (
        <ul
            onMouseDown={(e) => e.stopPropagation()}
            onClick={(e) =>
                props.handleHeaderClick(
                    header.level,
                    header.treepath,
                    header.containsLaw,
                    header.sections,
                    header.secNum,
                    header.objectId,
                    header.id,
                    e.stopPropagation(),
                )
            }
        >
            {header._id}
            {/* // if savedIndex === CurrentParent Index */}
            {props.headerIndex === header.objectId &&
                props.headers2.map((node2) => (
                    <HeaderList key={node2.objectId} header={node2} props={props} />
                ))}
            {props.headerIndex2 === header.objectId &&
                props.headers3.map((node3) => (
                    <HeaderList key={node3.objectId} header={node3} props={props} />
                ))}
            {props.headerIndex3 === header.objectId &&
                props.headers4.map((node4) => (
                    <HeaderList header={node4} key={node4.objectId} props={props} />
                ))}
        </ul>
    );
};

export default TocContent;

I understand this is maybe not the cleanest code, but an improvement nonetheless. If someone wants to propose something better, it will be much appreciated.

Dom355
  • 171
  • 2
  • 15