Shepherd Shepherd - 12 days ago 5
React JSX Question

Passing properties through components in ReactJS, ES6 example

I'm new to React and need some help. I'm trying to rewrite this Facebook's offical example into something own in ES6:

http://codepen.io/gaearon/pen/rrJNJY?editors=0010#0

My code looks like this:

class Person extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<h3>{this.props.user.name}</h3>
<h4>{this.props.user.surname}</h4>
<h4>{this.props.user.age}</h4>
</div>
)
}
}

class VisualAppearance extends Component {
render() {
return(
<div>
<p>{this.props.user.visuals.eyes}</p>
<p>{this.props.user.visuals.height}</p>
<p>{this.props.user.visuals.hair}</p>
</div>
);
}
}

class CreatePerson extends Component {
render() {
return(
<div>
<h1>Personal Info: </h1>
<Person user={this.props.user}/>
<h1>Visual Appearance: </h1>
<VisualAppearance user={this.props.user}/>
<h1>Time Created:</h1>
<p>{this.props.dateCreated}</p>
</div>
);
}
}

var use = {
user: {
name: 'Dude',
surname: 'Dude Surname',
age: 30,
visuals: {
eyes: 'blue',
height: 180,
hair: 'dark'
}
},
dateCreated: new Date()
}

ReactDOM.render(
<CreatePerson name={use.user.name}
surname={use.user.surname} age={use.user.age} eyes={use.user.visuals.eyes} height={use.user.visuals.height}
hair={use.user.visuals.height} date={use.user.dateCreated}
/>
, document.getElementById('project'));


I get the following error:
Cannot read property 'name' of undefined


If I change this just to
this.props.user
it goes through but the same error as above is reported on the surname.

In the link provided there is:
props.user.avatarUrl
, so it's a nested structure of the object.

How can I make this work and nesting object's properties like
this.props.sth.sthElse.sthElse1
on ES6 Classes in React?

Answer

CreatePerson expects a property called user here:

class CreatePerson extends Component {
    render() {
        return(
            <div>
                <h1>Personal Info: </h1>
                <Person user={this.props.user}/>            // <====
                <h1>Visual Appearance: </h1>
                <VisualAppearance user={this.props.user}/>  // <====
                <h1>Time Created:</h1>
                <p>{this.props.dateCreated}</p>
            </div>
        );
    }
}

You're not passing it one. You're passing it name, surname, and a bunch of others, but not user.

It works if you remove all those individual properties and pass it user instead:

ReactDOM.render(
    <CreatePerson user={use.user} />
    , document.getElementById('project'));

Example:

class Person extends React.Component {
    constructor(props) {
        super(props);
    }
    render() {
        return (
            <div>
                <h3>{this.props.user.name}</h3>
                <h4>{this.props.user.surname}</h4>
                <h4>{this.props.user.age}</h4>
            </div>
        )
    }
}

class VisualAppearance extends React.Component {
    render() {
        return(
          <div>
              <p>{this.props.user.visuals.eyes}</p>
              <p>{this.props.user.visuals.height}</p>
              <p>{this.props.user.visuals.hair}</p>
          </div>
        );
    }
}

class CreatePerson extends React.Component {
    render() {
        return(
            <div>
                <h1>Personal Info: </h1>
                <Person user={this.props.user}/>
                <h1>Visual Appearance: </h1>
                <VisualAppearance user={this.props.user}/>
                <h1>Time Created:</h1>
                <p>{this.props.dateCreated}</p>
            </div>
        );
    }
}

var use = {
    user: {
        name: 'Dude',
        surname: 'Dude Surname',
        age: 30,
        visuals: {
            eyes: 'blue',
            height: 180,
            hair: 'dark'
        }
    },
    dateCreated: new Date()
}

ReactDOM.render(
    <CreatePerson user={use.user} />
    , document.getElementById('project'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="project"></div>