Uros
Uros

Reputation: 323

React recursion - can't get correct value

I'm having Array of Objects named items. Each Object looks like this

interface IItem {
 id: string;
 title: string;
 items: IItem[] | null
}

So I'm doing recursion, as in

parent component:

        {items?.map((folder, index) => (
          <Item
            onClick={(event) => {
              event.stopPropagation();
              event.preventDefault();
              console.log(
                event.target.innerHTML,
                folder.id,
                folder.title
              );
            }}
            key={folder.id}
            data={folder}
          />
        ))}

WhileItem component looks like this:

const nestedItems =
    data.items
      ? data.items.map((item, index) => (
          <Item
            onClick={onClick}
            key={item.id}
            data={item}
          />
        ))
      : null;

  return (
    <div>
      <button onClick={onClick}>
        <Typography>
          {data.title} {data.id}
        </Typography>
      </button>
      <div>{nestedItems}</div>
    </div>

Html output and whats rendered in browser looks correct, but when I try to get {id}, or {title} from item in parent component the output of any click which has parent doesn't log it's own id, but it's parent id. The strange thing is that console.log from above on any "not first level items" looks like this:

event.target.innerHTML - correct value folder.id, folder.title - has parent ? parent id value : it's own id value

So I'm not really sure what's happening and where is the catch :/

Thanks in advance!

Upvotes: 0

Views: 65

Answers (1)

Henry Woody
Henry Woody

Reputation: 15662

You only define onClick for each of the root-level Items and then within the Item component you just pass the onClick prop to the child. Thus every child has the same onClick function as its parent.

To fix this you can change onClick to be more generic by accepting data (the id and/or other information) rather than having data curried into it. This way the onClick function passed to the Item works for any item, but the onClick function passed to the button within each Item is unique to that item.

For example:

Parent component:

{items?.map((folder, index) => (
    <Item
      onClick={(event, clickedFolder) => {
        event.stopPropagation();
        event.preventDefault();
        console.log(
          event.target.innerHTML,
          clickedFolder.id,
          clickedFolder.title
        );
      }}
      key={folder.id}
      data={folder}
    />
))}

Item component:

const nestedItems =
  data.items
    ? data.items.map((item, index) => (
        <Item
          onClick={onClick}
          key={item.id}
          data={item}
        />
      ))
    : null;

return (
  <div>
    <button onClick={event => onClick(event, data)}>
      <Typography>
        {data.title} {data.id}
      </Typography>
    </button>
    <div>{nestedItems}</div>
  </div>
)

Upvotes: 1

Related Questions