Leff
Leff

Reputation: 1320

React passing properties to children

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

Answers (3)

zavjs
zavjs

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

Dyo
Dyo

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

Tiago Alves
Tiago Alves

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

Related Questions