Section 4 - Props

Passing Properties to Components

  1. props are a way for high-level components to pass information to lower-level components. Continuing on our last example, let’s say this time we have our data in App.js instead of GroceryList.js, what should we do?

  1. Let’s first the const data to App.js. Now, we can pass the data constant to the GrocerList component by so:

<GroceryList chooseYourOwnPropertyName={data} />

  1. This creates a property named chooseYourOwnPropertyName, and it’s now available in the GroceryList component! Now head to GroceryList.js. To access the passed in information, we can read from this.props.chooseYourOwnPropertyName like so:

{this.props.propertyName.map((item)=>

<li key={item.key}>{item.name}</li>

)}

  1. Needless to say, chooseYourOwnPropertyName can be anything. Good props names are ones that are concise and easily understandable. So in real life, I would probably name it like so:

<GroceryList data={data} />

  1. And access it like so:

{this.props.data.map((item)=>

<li key={item.key}>{item.name}</li>

)}

  1. Why are props useful? Why can’t we just store the data constant in GroceryList.js? Let’s consider another use case for our grocery list application. What if we want to display multiple grocery lists with different contents? Let’s say we need a grocery list for Monday, Tuesday and Wednesday like so:

const mondayList = [{

               key: "1",

               name: "Bread"

              },

              {

                key: "2",

                name: "Peanut Butter"

              },

              {

                key: "3",

                name: "Jelly"

              }]

const tuesdayList = [{

               key: "4",

               name: "Cereal"

              },

              {

                key: "5",

                name: "Cup noodles"

              }]

const wednesdayList = [{

               key: "6",

               name: "Beer"

              }]

  1. As an exercise, try displaying all three lists in <GroceryList /> without using props.

  1. You won’t be able to do it! One stupid way to get around the issue is to create three components <MondayGroceryList />, <TuesdayGroceryList />, <WednesdayGroceryList />. Then, render mondayList in <MondayGroceryList />, tuesdayList in <TuesdayGroceryList /> and wednesdayList in <WednesdayGroceryList />. Then, import all three components into App.js, then finally render all three components in <App />. I’m disgusted just from typing this because there is SO MUCH REDUNDANCY! Having repeated code is a HUGE red flag in React.

  1. Instead, props make our lives much easier. We just pass each list into a GroceryList component like so:

<GroceryList data={mondayList} />

<GroceryList data={tuesdayList} />

<GroceryList data={wednesdayList} />

  1. The GroceryList component should not have to worry about the data, it should just blindly receive data and display it. The GroceryList component is only concerned about how things look. These are called presentational components.

  1. Let’s expand on the topic a bit. Let’s try passing more than one props to a component! Let’s say we also want to display the day of the week before the list. We can do it like so:

<GroceryList dayOfWeek={“Monday”} data={mondayList} />

<GroceryList dayOfWeek={“Tuesday”} data={tuesdayList} />

<GroceryList dayOfWeek={“Wednesday”} data={wednesdayList} />


  1. Then, in GroceryList.js, we can display the day of week like so:

      <div>

        <h3>{this.props.dayOfWeek}</h3>

        <ol>

{this.props.data.map((item)=><li>key={item.key}>{item.name}</li>)}

        </ol>

      </div>

Default Props

  1. Now just as an experiment, try not passing the “data” props to <GroceryList /> and see what would happen:

        <GroceryList data={data} />

  1. The whole app breaks!

TypeError: Cannot read property 'map' of undefined

  1. This is because we did not pass in the “data” props to GroceryList.js, and the value of this.props.data is now undefined! As your application starts to get larger, props passing can get messy. One way to avoid your application from breaking due to undefined props values is to set default props. Underneath the class declaration, type in the following:

GroceryList.defaultProps = {

  data:[]

}

  1. Now, when nothing is passed to the “data” props, it will be set to the default value of an empty array!

Type Checking with PropTypes

  1. Another good practice is to ensure all passed in props are of the expected type! In our case, we want to ensure that “data” is an array. To do that, we first have to import PropTypes on the top of the file:

import PropTypes from 'prop-types';

  1. Then, similar to defaultProps, we just put in:

GroceryList.propTypes = {

  data: PropTypes.array

};

  1. On top of PropTypes.array, there are also a huge variety of other types you can check for! For example, PropTypes.string for strings and PropTypes.number for numbers. Check out this article for more details.

  1. If we want to get super strict and safe, and that we want to make sure that “data” props contains an array of objects with the keys “key” and “name” both being a string, we could! We could write something like:

GroceryList.propTypes = {

  data: PropTypes.arrayOf(PropTypes.shape({

    key: PropTypes.string,

    name: PropTypes.string

  })),

};

  1. The code should be relatively self-explanatory. We made sure that the “data” props is an array of objects, with the key “key” being a string and “name” also being a string! Now if the “data” props is being passed anything else other than what we specified, you will see a huge red error message in the browser’s console. This is super helpful for debugging!

Summary

In this section, we explored props, short for properties, in React. We learnt how to pass props from the parent component and how to access the passed props from the child component. We also discussed why props are useful. Finally, we learnt about giving props default values with defaultProps, and type checking props with propTypes.

This wraps up our discussion. Next time, we will look at props’s cousin - state!

Final Code

Here is the code for this section.