Home > other >  Type for sending array of objects to child component so index [1] doesn't have to be specified
Type for sending array of objects to child component so index [1] doesn't have to be specified

Time:03-14

The API returns an array of objects that looks like this:

[
    {
        "id": 1,
        "odd": 7,
        "even": 42
    },
    {
        "id": 2,
        "odd": 1,
        "even": 2
    },
    {
        "id": 3,
        "odd": 31,
        "even": 6
    },
    {
        "id": 4,
        "odd": 17,
        "even": 62
    },
    {
        "id": 5,
        "odd": 13,
        "even": 4
    },
    {
        "id": 6,
        "odd": 21,
        "even": 12
    }
]

I want to pass this to a child component that iterates through the area of objects and prints out id, odd, and even.

What I can get working is doing the following:

// ParentComponent.tsx
...
<ChildItems {...response} />
...
// ChildComponent.tsx

type ReponseProps = {
  id: number;
  odd: number;
  even: number;
}[];


const ChildItems = (props: ResponseProps): JSX.Element => {
  console.log(props);
  return <></>;
};

Which creates an object that looks like:

{
  "0": {
      "id": 1,
      "odd": 7,
      "even": 42
  },
  "1": {
      "id": 2,
      "odd": 1,
      "even": 2
  },
  "2": {
      "id": 3,
      "odd": 31,
      "even": 6
  },
  "3": {
      "id": 4,
      "odd": 17,
      "even": 62
  },
  "4": {
      "id": 5,
      "odd": 13,
      "even": 4
  },
  "5": {
      "id": 6,
      "odd": 21,
      "even": 12
  }
}

Then I have to do something like the following to access each element:

const ChildItems = (props: SolutionProps): JSX.Element => (
  <>
  {
    Object.entries(props).map((item, index) => {
      return (
        <p key={item[1].id}>{item[1].even} - {item[1].odd}</p>
      )
    })
  }
  </>
);

What strikes me as weird is having to do item[1]: messy and seems like it shouldn't be necessary.

So that is my question: How should I build the passing of props to a child component, and type in the child component, to get around having to specify the index?

I've tried doing the following in the parent component:

// ParentComponent.tsx
...
<ChildComponent res={response} />
...

// ChildComponent.tsx
const ChildItems = (res: SolutionProps): JSX.Element => 
  ... 

But always get a: Property 'res' does not exist on type 'IntrinsicAttributes & SolutionProps'.

Probably a way to this and I'm just screwing it up.

CodePudding user response:

Props should be a plain object, not an array, where each property of the props argument is treated similarly to an argument in a normal function. Right now, you're typing the props as an array, and you're also not passing an array, but an object as props when you do

<ChildItems {...response} />

(which spreads each enumerable own property of the response into the props object - resulting in your { 0: ... 1: ... } structure that's hard to work with)

Change to something like:

<ChildItems {...{ response }} />
// or
<ChildItems response={response} />

and

const ChildItems = ({ response }: { response: ResponseProps }) => {
  • Related