Chapter 3. What exactly are props? | Delightful React

In the previous post First steps with Next.js , we discussed about Next.js, a react framework using which we can build react apps without hassle. We also talked about React components and composition. In this post, let us talk about one of the most important concepts in react - props.

JS Expressions in JSX

Before moving on to props, let us discuss how to write JS expressions in jsx. By default, whatever is written in jsx tags is taken as a string by React. To tell React not to treat an expression as a string, but as JavaScript, we wrap it with curly braces {}.

Let us look at a few examples:

  • We can access values from any kind of a variable in the scope of the component from within jsx like so:

    function Home() {
      const greeting = "Hello World"
      const num = 2
      return (
        <div>
          <p>{greeting} {num}</p>
          {/*Comments are not supported by JSX, they are a part of JS only. So without braces, comments will be evaluated as strings too!*/}
        </div>
      )
    }
    
  • We can also write a conditional in jsx:

    function Home() {
      const greeting = "Hello World"
      const num = 2
      const disabled = true
      return (
        <p>
          {
            disabled ? "disabled" : greeting + num
          }
        </p>
      )
    }
    

    Basically, any expression in jsx within curly braces is evaluated as JavaScript.

Props

What exactly are props?

Props are the primary way of communication in React. Data in react flows from top to down, meaning, any component can pass in data to its child components. This happens via props.

As we discussed earlier, components are simply functions and functions can take in arguments. Therefore, we can pass components some arguments when we call (render) them. We call these arguments props.

A Brief History Lesson

The reason we call the arguments props is that when react first started, the components we not functions, they were classes. There was also a syntax before that, called React.createClass. They were not even exactly classes to begin with. React goes a long way. It was started in 2013 and the api was very different from what we see today. So, props was what they used to call it then. As of today, they are very similar to arguments.

Passing Props To Components

Though props are similar to arguments, the way we pass in these arguments is different. Let us see props in action: Recall that we had rendered three paragraph elements in the last post like so:

function MyParagraph(){
  return <p>Hello World</p>
}
function MyParagraph2(){
  return <p>Hello World2</p>
}
function MyParagraph3(){
  return <p>Hello World2</p>
}
function Home() {
  return (
    <div>
      <MyParagraph></MyParagraph>
      <MyParagraph2></MyParagraph2>
      <MyParagraph3></MyParagraph3>
    </div>
  )

}

As we discussed earlier, except for the text inside, the three paragraph components are the same. Let us see how we can optimise this code with props. I don't want three different paragraph components. Instead, I want a single paragraph component which shows whatever text I pass to it as an argument (prop).

  1. Let us start by deleting components MyParagraph2 and MyParagraph3 and calling MyParagraph again in their place like so:

    function MyParagraph(){
     return <p>Hello World</p>
    }
    
    function Home() {
     return (
       <div>
         <MyParagraph></MyParagraph>
         <MyParagraph></MyParagraph>
         <MyParagraph></MyParagraph>
       </div>
     )
    }
    

    This will now render "Hello World" thrice.

  2. Now, let's pass it the text want it to show each time it renders as a string.

    function Home() {
     return (
       <div>
         <MyParagraph text="Hello World"></MyParagraph>
         <MyParagraph text="Hello World2"></MyParagraph>
         <MyParagraph text="Hello World3"></MyParagraph>
       </div>
     )
    }
    

    This doesn't do anything just yet.

  3. All components receive the collection of props passed by their parent as the first argument in the form of an object. Home is the parent of MyParagraph as it has rendered it. Similarly, Next.js renders the Home component internally in the route. Therefore, we can access the text prop in MyParagraph by extracting it from the props object passed to it as an argument. Let us log props to the console.

    function MyParagraph(props){
     console.log(props)
     return <p>Hello World</p>
    }
    

    So here, an object gets logged for each paragraph. Each object has a text key with a value that we passed in while rendering.

  4. Since we now know how to access props, let us use props to render jsx. Now instead of rendering "Hello World" let us render the text passed in:

    function MyParagraph(props){
     console.log(props)
     return <p>{props.text}</p>
    }
    

    This will return the text passed from props! Recall that to evaluate an expression as JS, it needs to be wrapped around curly braces.

Note that

  1. props are case sensitive, so something like this will throw an error:

    function MyParagraph(props){
     return <p>{props.Text}</p>
    }
    
    function Home() {
     return (
       <div>
         <MyParagraph text="hello world"></MyParagraph>
       </div>
     )
    }
    
  2. You can pass in as many props you want:

    function MyParagraph(props){
     const text = props.text
     const disabled = props.disabled
     return <p>{disabled ? "disabled": text}</p>
    }
    function Home() {
     return (
       <div>
         <MyParagraph text="hello world" disabled={true}></MyParagraph>
         {/*note that boolean - true is wrapped around braces*/}
       </div>
     )
    }
    
  3. A better way to extract props would be to use object destructuring .

    function MyParagraph(props){
      const {text, disabled} = props
      return <p>{disabled ? "disabled": text}</p>
    }
    function Home() {
      return (
        <div>
          <MyParagraph text="hello world" disabled={true}></MyParagraph>
          {/*note that boolean - true is wrapped around braces*/}
        </div>
      )
    }
    

    We will be using this syntax moving forward.

So what exactly are props?

  • In one way they are analogous to arguments passed to a function.
  • Props are simply arguments to a component to make components behave differently in different scenarios.
  • Props flow top-down. A parent can send props to it's children but not the other way around.
  • There is a way for children to talk to the parent via props. This can be achieved by passing functions as a prop to a child component. We will discuss that very soon in an upcoming tutorial.

I hope this was useful. In the next post, let us discuss how React works behind the scenes with virtualDOM.

Thanks!

No Comments Yet