Course: Section

Get Started with Modern React: Learn by Doing

Episode: Title

S03・V07: Passing Props

Date Created: July 17th, 2019
Last Updated: 27 days ago

Objectives
  1. We will refactor the Board component so that the rendering of a Square is pulled out into a separate function.
  2. We will show how to pass data in one direction from a parent component down to a child component, using the so-called props object.
Watch Video
Duration: 5m 23s

Refactor the Board

First, we will refactor the Board component. Let’s create a function to render each Square, in which we can add functionality later. We will call it renderSquare, and it will return a Square.

  const renderSquare = () => {
    return (
      <Square />
    );
  };

Now, we will remove all the Square components in the return expression. In their place, we will add a JSX container. Now invoke the renderSquare function.

const Board = () => {
  const renderSquare = () => {
    return (
      <Square />
    );
  };

  return (
    <div style={{
      backgroundColor: 'skyblue',
      margin: 40,
      padding: 20,
    }}>
      Board
      <div className="board-row">
        {renderSquare()}        {renderSquare()}        {renderSquare()}      </div>
      <div className="board-row">
        {renderSquare()}        {renderSquare()}        {renderSquare()}      </div>
      <div className="board-row">
        {renderSquare()}        {renderSquare()}        {renderSquare()}      </div>
    </div>
  );
};

Ensure there is no visual difference in the browser. All we have done is refactor the code, without adding any styling or behavior.

Passing Props

Now we will add a prop to the rendered Square in the renderSquare function. Call the prop value and pass it the literal string of O for illustration purposes.

  const renderSquare = () => {
    return (
      <Square value="0" />    );
  };

When a prop is added to a child component, React passes an object, which is called props, to that component. The props object can be read from the child component.

In this example, the Board parent component is passing data to the Square child component. The string value of O is being passed from the Board to the Square. Within React components, the props object is passed in as an argument. So, we can add props as the input to the Square function component.

const Square = props => {  return (
    <div className="square">
      X
    </div>
  );
};

Now, let’s add a console.log() statement to print out the props object.

const Square = props => {
  console.log('props:', props);
  return (
    <div className="square">
      X
    </div>
  );
};

Open Chrome’s developer console. Open the tab “Console” and refresh the browser page. The props object is printed out 9 times, once for each rendered Square. We can see that each props object has the prop value with a O inside.

Let’s show the prop value in our game interface. Instead of the X string literal, add a JSX container, and inside it, put props.value to read the value from the props object.

const Square = props => {
  console.log('props:', props);

  return (
    <div className="square">
      {props.value}    </div>
  );
};

View the browser to see each square display a O. We have successfully passed the prop value in the props object from the Board parent component to the Square child component.

This is called “passing props” in React.

Differentiating Squares

Now, let’s set an index value on each rendered Square, so that we can differentiate them and reference them individually. We will call the index: i. Now we will pass the index to the Square as its value prop. Since the index represents a JavaScript variable, and not a string literal, we will need to wrap it inside a JSX container.

  const renderSquare = i => {    return (
      <Square value={i} />    );
  };

Remove the console.log() statement from the Square component.

We now need to call the individual renderSquare functions with 9 different index values, starting from 0 for the top left square, through 8 for the bottom right square.

import React from 'react';
import ReactDOM from 'react-dom';

import './index.css';

const Square = props => {
  return (
    <div className="square">
      {props.value}
    </div>
  );
};

const Board = () => {
  const renderSquare = i => {
    return (
      <Square value={i} />
    );
  };

  return (
    <div style={{
      backgroundColor: 'skyblue',
      margin: 40,
      padding: 20,
    }}>
      Board
      <div className="board-row">
        {renderSquare(0)}        {renderSquare(1)}        {renderSquare(2)}      </div>
      <div className="board-row">
        {renderSquare(3)}        {renderSquare(4)}        {renderSquare(5)}      </div>
      <div className="board-row">
        {renderSquare(6)}        {renderSquare(7)}        {renderSquare(8)}      </div>
    </div>
  );
};

const Game = () => {
  return (
    <div className="game">
      Game
      <Board />
    </div>
  );
};

ReactDOM.render(
  <Game />,
  document.getElementById('root')
);

View the browser to see each square display its own index value.

It is important to know that props can only be passed from parent to child, never the other way. This unidirectional data flow is a feature of React. It makes it easier to keep track of data, and is less error-prone.

Summary

We did some refactoring, and we showed you how to pass props from a parent component to a child component.

Next Up…

In the next video, we will enable the user to interact with each square via a mouse click.