Get Started with Modern React: Learn by Doing
S03・V07: Passing Props
- We will refactor the Board component so that the rendering of a Square is pulled out into a separate function.
- 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.
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.