Passing a Nested Object as React.Component Props

Viewed 1422

I'm sure this was asked before but I can't find it. I'm trying to pass a nested object as props into a React.Component class but I keep getting this error:

react-dom.development.js:13231 Uncaught Error: Objects are not valid as a React child (found: object with keys {props, context, refs, updater}). If you meant to render a collection of children, use an array instead.

I have an App.tsx file created like this:

import React from "react";

export type Child = {
    id: number
}

export type Parent = {
    id: number,
    child: Child
}

export class Card extends React.Component<Parent> {
    render() {
         return <div>
              Parent ID: {this.props.id}
              Child ID: {this.props.child.id}
         </div>;
    }
}

function App() {
    const data: any = {
         "id": 1,
         "child": {
              "id": 2
         }
    }
    
    const card: Card = new Card(data);

    return (
        <div className="app">
              {card}
        </div>
    );
}

export default App;

Is this sort of thing not possible? It seems like it should be but maybe I am missing something. Is there a way to make something like this work or a correct pattern that I am not using? Thanks!

2 Answers

Theere is no "one" correct way to pass an object down to a child component, there are multiple approaches, one of which is the following (using your example):

import React from "react";

export type Child = {
    id: number
}

export type Parent = {
    id: number,
    child: Child
}

export class Card extends React.Component<Parent> {
    render() {
         return <div>
              Parent ID: {this.props.id}
              Child ID: {this.props.child.id}
         </div>;
    }
}

function App() {
    const data: any = {
         "id": 1,
         "child": {
              "id": 2
         }
    }
    
 
    return (
        <div className="app">
              <Card  {...data} />
        </div>
    );
}

export default App;

I'm pretty sure for this to work you'd have to change

<div className="app">
    {card}
</div>

TO:

<div className="app">
    <card />
</div>

BUT, like Jack said in the comments, you shouldn't be instantiating React components like this anyway. Instead of doing:

const card: Card = new Card(data);

You should just do:

<div className="app">
    <Card {...data} />
</div>
Related