React Props

React Props

Introduction

React is composed of Components that represent parts of the UI that the user interacts with. When you are first learning react, it can be hard to see the similarity between components and regular javascript functions when in fact they are basically the same thing!

Functions in javascript set up parameters for the data it is expecting to receive when it is called. When a function is called, arguments are sent in and are received via those parameters. For example:


/* 
    the sum function is expecting 2 parameters
    num1 and num2
*/

function sum(num1, num2){
    return num1 + num2
}

/*
    When the function is called with (), the
    arguments are fed into the function 
    parameters
*/

sum(10, 20) // => returns 30

React components work very similarly, they are defined as functions and expect some parameters. These parameters are what we call props!

What are 'props'?

In React, data flow in uni-directional. This means that data is passed "down" from parent components to child components. Examples of this will be shown below, but it is essentially a function calling another function and giving it arguments.

Props is always a javascript object that contains all of the arguments passed into the component when it is called, so here is that same sum function example again but expressed in the react component syntax:

/*
    First we declare our component and tell it 
    to expect a parameter called 'props'. Since
    props is an object, the two arguments passed
    in are accessed by first saying 'props.', and 
    then the argument name.
*/

function Sum(props){
    return props.num1 + props.num2
}

/*
    Using the < /> syntax to call the Sum 
    component (instead of the regular () syntax), 
    the two props 'num1' and 'num2' 
    are passed in as arguments.
*/

<Sum num1={10} num2={20}/>

Components will automatically take all the props given to it when it is called, (such as num1={10}), and will put them in the object we call props as a key value pair! With the Sum component above, the props object looks like this:

const props = {
    num1: 10,
    num2: 20
}

Why are props important?

Composing your website out of components that receive props is a way to keep your code organized and DRY. Components are meant to be written like functions in the sense that they should be dynamic and re-useable. Let's see an example of this, say we were making Twitter and wanted to make a component for a Tweet, something our site will have millions of. It would make NO sense to write a new tweet component for every tweet added to the website, instead we should only have to write our component once and then re-use it for every tweet on the site.

First we declare the component and put props as the parameter:

function Tweet(props){
   
}

Then we tell it what to return, for now we will just be returning the tweet text in a <p></p> tag.

import React from 'react'

function Tweet(props){
   return (
       <p>{props.text}</p>
   )
}

There are a few things to notice here. First, notice my return statement uses () directly after it so that you can write your JSX with proper indentation.

Additionally, when you are displaying a variable in your JSX, such as props.text, you have to wrap it in a set of {} to let React know that this is a variable and not just static text. props.text is the prop we will pass into the component that contains the text of the tweet.

Now to the fun part, using that component! Here we have a TweetList component that is importing the Tweet component and rendering out a single Tweet.

import React from 'react'
import Tweet from './Tweet.js'

function TweetList(){
    return (
        <div>
            <Tweet text={"This is my very first tweet!"}/>
        </div>
    )
}

The above code would render the following <p> tag to the DOM.

<div>
    <p>This is my very first tweet!</p>
</div>

The Tweet component received a props.text with the text This is my very first tweet!. As instructed in the component declaration, that prop was then put inside of a <p> tag and returned.

Now that we know that the <Tweet /> component is working as expected, we can use it again for the next tweet this user made.

import React from 'react'
import Tweet from './Tweet.js'

function TweetList(){
    return (
        <div>
            <Tweet text={"This is my very first tweet!"}/>
            <Tweet text={"My second tweet, I'm on fire!"}/>
        </div>
    )
}

And the corresponding HTML would come out looking like this:

<div>
    <p>This is my very first tweet!</p>
    <p>My second tweet, I'm on fire!</p>
</div>

This is the purpose of components. As the developer, you write the component once with the intent of it being reusable, and then use it over and over again by providing it different data. Note the prop being passed into the <Tweet /> component is called the same on both, text, but the value that text prop represents is different. Going back to the very beginning of this article, it would be like calling the sum function twice, such as:

sum(10, 20) //  30
sum(5, 4)   //  9

The sum function is executing the same way with both of these function calls but produce different output depending on the arguments passed in. Swap the word argument with props, and you have react!

What can be a 'prop'?

If you are wondering what kind of data can be passed as props just think, "what can a regular javascript function take as an argument"? They are the same, so props can be strings, numbers, booleans, arrays, objects and functions.

In the example of the Tweet we just passed a single string prop down, so let's look at an example of passing multiple props. I will be giving the <div>'s classNames so that when I show you the HTML equivalent, you can see how it lands on the HTML page.

Here is a BlogPost component that takes a title, bodyText, imgUrl and date props.

import React from 'react'

function BlogPost(props){
    return (
        <div className="post-container">
            <h1>{props.title}</h1>
            <p>{props.bodyText}</p>
            <img src={props.imgUrl}/>
            <span>{props.date}</span>
        </div>
    )
}

And here is a BlogList component rendering out two BlogPost components and passing them their needed props.

import React from 'react'
import BlogPost from './BlogPost.js'

function BlogList(){
    return (
        <div className="blog-list-container>
            <BlogPost 
                title={"My first post!"}
                bodyText={"This is all the text for the blogpost!"}
                imgUrl={"https://www.fake-imgs.com/img1.jpeg"}
                date={"January 12th, 2019}
            />
            <BlogPost 
                title={"My second post!"}
                bodyText={"I don't have much to write about today."}
                imgUrl={"https://www.fake-imgs.com/img2.jpeg"}
                date={"January 15th, 2019}
            />
        </div>
    )
}

Once this BlogList component renders to the DOM, it would show up like this in HTML:

<div class="blog-list-container">
    <div class="post-container">
        <h1>My first post!</h1>
        <p>This is all the text for the blogpost!</p>
        <img src="https://www.fake-imgs.com/img1.jpeg"/>
        <span>January 12th, 2019</span>
    </div>
    <div class="post-container">
        <h1>My second post!</h1>
        <p>I don't have much to write about today.</p>
        <img src="https://www.fake-imgs.com/img2.jpeg"/>
        <span>January 15th, 2019</span>
    </div>
</div>

Conclusion

This has been a very brief introduction to props, but hopefully gets you on the right foot to start playing with them in your own code. All of these examples only dealt with 2 components, a parent that passed props to a child. Be aware though that in production code, you would have many many more components and possibly be passing props down 4+ levels deep. For example:

<BlogList />
    <BlogPost />
        <BlogHeader />
            <BlogImg />
            <BlogTitle />
        <BlogBody />
            <BodyHeader />
            <BodyMain />
            <BodyFooter />

In this example, BlogList would pass props to BlogPost. BlogPost would then pass the appropriate props to BlogHeader and BlogBody an so on. Just remember props are ALWAYS passed down from parent component to child component and are meant to help you keep your components clean and re-usable.