Reputation: 1320
I was reading React docs, about Components and props here. One thing got me confused. In this part of the code, where we pass the props to Avatar Component:
function Comment(props) {
return (
<div className="Comment">
<div className="UserInfo">
<Avatar user={props.author} />
<div className="UserInfo-name">
{props.author.name}
</div>
</div>
<div className="Comment-text">
{props.text}
</div>
<div className="Comment-date">
{formatDate(props.date)}
</div>
</div>
);
}
And where the comment object looks like this:
const comment = {
date: new Date(),
text: 'I hope you enjoy learning React!',
author: {
name: 'Hello Kitty',
avatarUrl: 'http://placekitten.com/g/64/64',
},
};
Since we are already passing only the author
property of the object, why do we then need to access author.name
and avatarUrl
like this in Avatar
component:
function Avatar(props) {
return (
<img className="Avatar"
src={props.user.avatarUrl}
alt={props.user.name}
/>
);
}
And, not like this, that would make more sense in Vue.js
, where I am coming from:
function Avatar(props) {
console.log(props);
return (
<img className="Avatar"
src={props.avatarUrl}
alt={props.name}
/>
);
}
Upvotes: 0
Views: 1750
Reputation: 378
I understand why you are confused. Note that each component (parent or child) have a different props object from each other. These are totally unrelated and may have a different set of properties.
So, by passing a value down as prop to a child component, you're not redefining that child's props object (to author, for example), instead, you're almost like appending a new value to it, which was initially empty.
For example,
// Parent props is: { author, posts }
const Parent = (props) => {
return (
/* Child props is a completely different -> object,
** now that nothing is being passed, an empty object -> {}
*/
<Child />
);
};
Now, if parent starts passing a new prop to Child, the Child props now holds the new value within its own props object:
// Parent props is: { author, posts }
const Parent = (props) => {
return (
/* Child props is a completely different object,
** now Child.props { author: Parent.props.author, age: "12" } */
<Child author={props.author} age="12" />
);
};
In essence, each component receives a different unique props object that is set in the initial phase of the component life.
Additionally I'd recommend you to use the object destructuring ES6 feature to save time from typing 'props.author':
const Child = ({ author, age, smoker }) => {
return <h2>Hey ${author.name}</h2>
};
Since props is the first argument passed to the Child component function, by setting it as an object in the signature, we're able to extract the specific values we need.
This is how it would look if we're on a class component, right within the render
method, but before returning of the React element. We're initialising const
, and assigning this.props
, in order to destructure the object and create a local identifier.
class MyComponent extends React.Component {
render() {
const { author, age, smoker } = this.props;
return (
<h2>Hey {author.name}</h2>
);
}
}
If you wish to know more about components, props, state and general life cycle here's a good resource this.
Upvotes: 1
Reputation: 4464
When you pass props to a component you simply access them by the property name the parent pass a value to, because you can pass multiple props this is needed.
To be able to access the props like in your last snippet you can use the object spread :
<Avatar {...props.author} />
Same as :
<Avatar avatarUrl={props.author.avatarUrl} name={props.author.name}/>
Upvotes: 1
Reputation: 2316
You are passing as user prop:
{
name: 'Hello Kitty',
avatarUrl: 'http://placekitten.com/g/64/64',
}
In the Child it will be:
props: {
user: {
name: 'Hello Kitty',
avatarUrl: 'http://placekitten.com/g/64/64',
}
}
To access it:
props.user.avatarUrl
props.user.name
Just remember that props
is an object, you are basically taking the value of author
, setting it to user
and attaching it to props
.
Upvotes: 0