Getting Started - React
Getting Started - React
html
Tip
This tutorial is designed for people who prefer to learn by doing. If you
prefer learning concepts from the ground up, check out our step-by-step
guide. You might find this tutorial and the guide complementary to each
other.
Setup for the Tutorial will give you a starting point to follow the tutorial.
Overview will teach you the fundamentals of React: components, props, and
state.
Completing the Game will teach you the most common techniques in
React development.
Adding Time Travel will give you a deeper insight into the unique strengths
of React.
You don’t have to complete all of the sections at once to get the value out of this
tutorial. Try to get as far as you can — even if it’s one or two sections.
In this tutorial, we’ll show how to build an interactive tic-tac-toe game with React.
You can see what we’ll be building here: Final Result. If the code doesn’t make
sense to you, or if you are unfamiliar with the code’s syntax, don’t worry! The goal of
this tutorial is to help you understand React and its syntax.
We recommend that you check out the tic-tac-toe game before continuing with the
tutorial. One of the features that you’ll notice is that there is a numbered list to the
right of the game’s board. This list gives you a history of all of the moves that have
occurred in the game, and it is updated as the game progresses.
You can close the tic-tac-toe game once you’re familiar with it. We’ll be starting from
a simpler template in this tutorial. Our next step is to set you up so that you can start
building the game.
Prerequisites
1 of 23 03/04/2020, 20:27
Tutorial: Intro to React – React https://reactjs.org/tutorial/tutorial.html
We’ll assume that you have some familiarity with HTML and JavaScript, but you
should be able to follow along even if you’re coming from a different programming
language. We’ll also assume that you’re familiar with programming concepts like
functions, objects, arrays, and to a lesser extent, classes.
If you need to review JavaScript, we recommend reading this guide. Note that we’re
also using some features from ES6 — a recent version of JavaScript. In this tutorial,
we’re using arrow functions, classes, let, and const statements. You can use the
Babel REPL to check what ES6 code compiles to.
First, open this Starter Code in a new tab. The new tab should display an empty tic-
tac-toe game board and React code. We will be editing the React code in this tutorial.
You can now skip the second setup option, and go to the Overview section to get an
overview of React.
If you get stuck, check out the community support resources. In particular, Reactiflux
Chat is a great way to get help quickly. If you don’t receive an answer, or if you
remain stuck, please file an issue, and we’ll help you out.
Overview
Now that you’re set up, let’s get an overview of React!
What Is React?
React is a declarative, efficient, and flexible JavaScript library for building user
interfaces. It lets you compose complex UIs from small and isolated pieces of code
called “components”.
React has a few different kinds of components, but we’ll start with React.Component
subclasses:
2 of 23 03/04/2020, 20:27
Tutorial: Intro to React – React https://reactjs.org/tutorial/tutorial.html
We’ll get to the funny XML-like tags soon. We use components to tell React what we
want to see on the screen. When our data changes, React will efficiently update and
re-render our components.
The render method returns a description of what you want to see on the screen.
React takes the description and displays the result. In particular, render returns a
React element, which is a lightweight description of what to render. Most React
developers use a special syntax called “JSX” which makes these structures easier to
write. The <div /> syntax is transformed at build time to
React.createElement('div'). The example above is equivalent to:
JSX comes with the full power of JavaScript. You can put any JavaScript expressions
within braces inside JSX. Each React element is a JavaScript object that you can
store in a variable or pass around in your program.
The ShoppingList component above only renders built-in DOM components like <div
/> and <li />. But you can compose and render custom React components too. For
example, we can now refer to the whole shopping list by writing <ShoppingList />.
Each React component is encapsulated and can operate independently; this allows
you to build complex UIs from simple components.
3 of 23 03/04/2020, 20:27
Tutorial: Intro to React – React https://reactjs.org/tutorial/tutorial.html
setup).
This Starter Code is the base of what we’re building. We’ve provided the CSS styling
so that you only need to focus on learning React and programming the tic-tac-toe
game.
By inspecting the code, you’ll notice that we have three React components:
Square
Board
Game
The Square component renders a single <button> and the Board renders 9 squares.
The Game component renders a board with placeholder values which we’ll modify
later. There are currently no interactive components.
To get our feet wet, let’s try passing some data from our Board component to our
Square component.
We strongly recommend typing code by hand as you’re working through the tutorial
and not using copy/paste. This will help you develop muscle memory and a stronger
understanding.
In Board’s renderSquare method, change the code to pass a prop called value to the
Square:
class Board extends React.Component {
renderSquare(i) {
return <Square value={i} />; }
}
Change Square’s render method to show that value by replacing {/* TODO */} with
{this.props.value}:
Before:
4 of 23 03/04/2020, 20:27
Tutorial: Intro to React – React https://reactjs.org/tutorial/tutorial.html
After: You should see a number in each square in the rendered output.
Let’s fill the Square component with an “X” when we click it. First, change the button
tag that is returned from the Square component’s render() function to this:
class Square extends React.Component {
render() {
return (
<button className="square" onClick={function() { alert('click'); }}> {this
</button>
);
}
5 of 23 03/04/2020, 20:27
Tutorial: Intro to React – React https://reactjs.org/tutorial/tutorial.html
If you click on a Square now, you should see an alert in your browser.
Note
To save typing and avoid the confusing behavior of this, we will use the
arrow function syntax for event handlers here and further below:
class Square extends React.Component {
render() {
return (
<button className="square" onClick={() => alert('click')}> {this.props
</button>
);
}
}
As a next step, we want the Square component to “remember” that it got clicked, and
fill it with an “X” mark. To “remember” things, components use state.
Note
In JavaScript classes, you need to always call super when defining the
constructor of a subclass. All React component classes that have a
constructor should start with a super(props) call.
Now we’ll change the Square’s render method to display the current state’s value
when clicked:
6 of 23 03/04/2020, 20:27
Tutorial: Intro to React – React https://reactjs.org/tutorial/tutorial.html
Put the className and onClick props on separate lines for better readability.
After these changes, the <button> tag that is returned by the Square’s render method
looks like this:
class Square extends React.Component {
constructor(props) {
super(props);
this.state = {
value: null,
};
}
render() {
return (
<button
className="square" onClick={() => this.setState({value: 'X'})} >
{this.state.value} </button>
);
}
}
When you call setState in a component, React automatically updates the child
components inside of it too.
Developer Tools
The React Devtools extension for Chrome and Firefox lets you inspect a React
component tree with your browser’s developer tools.
7 of 23 03/04/2020, 20:27
Tutorial: Intro to React – React https://reactjs.org/tutorial/tutorial.html
The React DevTools let you check the props and the state of your React components.
After installing React DevTools, you can right-click on any element on the page, click
“Inspect” to open the developer tools, and the React tabs (“࿔࿖ Components” and “࿔
࿕ ࿖
࿕
࿖ Components” to inspect
࿕
Profiler”) will appear as the last tabs to the right. Use “࿔
the component tree.
However, note there are a few extra steps to get it working with CodePen:
Lifting State Up
Currently, each Square component maintains the game’s state. To check for a winner,
we’ll maintain the value of each of the 9 squares in one location.
8 of 23 03/04/2020, 20:27
Tutorial: Intro to React – React https://reactjs.org/tutorial/tutorial.html
We may think that Board should just ask each Square for the Square’s state.
Although this approach is possible in React, we discourage it because the code
becomes difficult to understand, susceptible to bugs, and hard to refactor. Instead,
the best approach is to store the game’s state in the parent Board component instead
of in each Square. The Board component can tell each Square what to display by
passing a prop, just like we did when we passed a number to each Square.
Lifting state into a parent component is common when React components are
refactored — let’s take this opportunity to try it out.
Add a constructor to the Board and set the Board’s initial state to contain an array of
9 nulls corresponding to the 9 squares:
class Board extends React.Component {
constructor(props) { super(props); this.state = { squares: Array(9).fill
renderSquare(i) {
return <Square value={i} />;
}
When we fill the board in later, the this.state.squares array will look something
like this:
[
'O', null, 'X',
'X', 'X', 'O',
'O', null, null,
]
In the beginning, we passed the value prop down from the Board to show numbers
from 0 to 8 in every Square. In a different previous step, we replaced the numbers
with an “X” mark determined by Square’s own state. This is why Square currently
ignores the value prop passed to it by the Board.
We will now use the prop passing mechanism again. We will modify the Board to
instruct each individual Square about its current value ('X', 'O', or null). We have
already defined the squares array in the Board’s constructor, and we will modify the
Board’s renderSquare method to read from it:
renderSquare(i) {
return <Square value={this.state.squares[i]} />; }
Each Square will now receive a value prop that will either be 'X', 'O', or null for
empty squares.
9 of 23 03/04/2020, 20:27
Tutorial: Intro to React – React https://reactjs.org/tutorial/tutorial.html
Next, we need to change what happens when a Square is clicked. The Board
component now maintains which squares are filled. We need to create a way for the
Square to update the Board’s state. Since state is considered to be private to a
component that defines it, we cannot update the Board’s state directly from Square.
Instead, we’ll pass down a function from the Board to the Square, and we’ll have
Square call that function when a square is clicked. We’ll change the renderSquare
method in Board to:
renderSquare(i) {
return (
<Square
value={this.state.squares[i]}
onClick={() => this.handleClick(i)} />
);
}
Note
We split the returned element into multiple lines for readability, and
added parentheses so that JavaScript doesn’t insert a semicolon after
return and break our code.
Now we’re passing down two props from Board to Square: value and onClick. The
onClick prop is a function that Square can call when clicked. We’ll make the
following changes to Square:
When a Square is clicked, the onClick function provided by the Board is called.
Here’s a review of how this is achieved:
1. The onClick prop on the built-in DOM <button> component tells React to set up
a click event listener.
2. When the button is clicked, React will call the onClick event handler that is
defined in Square’s render() method.
3. This event handler calls this.props.onClick(). The Square’s onClick prop was
specified by the Board.
4. Since the Board passed onClick={() => this.handleClick(i)} to Square, the
Square calls this.handleClick(i) when clicked.
5. We have not defined the handleClick() method yet, so our code crashes. If you
10 of 23 03/04/2020, 20:27
Tutorial: Intro to React – React https://reactjs.org/tutorial/tutorial.html
click a square now, you should see a red error screen saying something like
“this.handleClick is not a function”.
Note
When we try to click a Square, we should get an error because we haven’t defined
handleClick yet. We’ll now add handleClick to the Board class:
render() {
const status = 'Next player: X';
return (
<div>
<div className="status">{status}</div>
<div className="board-row">
{this.renderSquare(0)}
{this.renderSquare(1)}
{this.renderSquare(2)}
</div>
<div className="board-row">
{this.renderSquare(3)}
{this.renderSquare(4)}
{this.renderSquare(5)}
</div>
<div className="board-row">
{this.renderSquare(6)}
{this.renderSquare(7)}
{this.renderSquare(8)}
</div>
</div>
);
}
}
11 of 23 03/04/2020, 20:27
Tutorial: Intro to React – React https://reactjs.org/tutorial/tutorial.html
After these changes, we’re again able to click on the Squares to fill them, the same as
we had before. However, now the state is stored in the Board component instead of
the individual Square components. When the Board’s state changes, the Square
components re-render automatically. Keeping the state of all squares in the Board
component will allow it to determine the winner in the future.
Since the Square components no longer maintain state, the Square components
receive values from the Board component and inform the Board component when
they’re clicked. In React terms, the Square components are now controlled
components. The Board has full control over them.
Note how in handleClick, we call .slice() to create a copy of the squares array to
modify instead of modifying the existing array. We will explain why we create a copy
of the squares array in the next section.
In the previous code example, we suggested that you use the .slice() method to
create a copy of the squares array to modify instead of modifying the existing array.
We’ll now discuss immutability and why immutability is important to learn.
There are generally two approaches to changing data. The first approach is to mutate
the data by directly changing the data’s values. The second approach is to replace the
data with a new copy which has the desired changes.
The end result is the same but by not mutating (or changing the underlying data)
directly, we gain several benefits described below.
Detecting Changes
12 of 23 03/04/2020, 20:27
Tutorial: Intro to React – React https://reactjs.org/tutorial/tutorial.html
Detecting changes in mutable objects is difficult because they are modified directly.
This detection requires the mutable object to be compared to previous copies of itself
and the entire object tree to be traversed.
The main benefit of immutability is that it helps you build pure components in React.
Immutable data can easily determine if changes have been made which helps to
determine when a component requires re-rendering.
You can learn more about shouldComponentUpdate() and how you can build pure
components by reading Optimizing Performance.
Function Components
In React, function components are a simpler way to write components that only
contain a render method and don’t have their own state. Instead of defining a class
which extends React.Component, we can write a function that takes props as input and
returns what should be rendered. Function components are less tedious to write than
classes, and many components can be expressed this way.
Note
Taking Turns
We now need to fix an obvious defect in our tic-tac-toe game: the “O”s cannot be
marked on the board.
We’ll set the first move to be “X” by default. We can set this default by modifying the
initial state in our Board constructor:
13 of 23 03/04/2020, 20:27
Tutorial: Intro to React – React https://reactjs.org/tutorial/tutorial.html
Each time a player moves, xIsNext (a boolean) will be flipped to determine which
player goes next and the game’s state will be saved. We’ll update the Board’s
handleClick function to flip the value of xIsNext:
handleClick(i) {
const squares = this.state.squares.slice();
squares[i] = this.state.xIsNext ? 'X' : 'O'; this.setState({
squares: squares,
xIsNext: !this.state.xIsNext, });
}
With this change, “X”s and “O”s can take turns. Try it!
Let’s also change the “status” text in Board’s render so that it displays which player
has the next turn:
render() {
const status = 'Next player: ' + (this.state.xIsNext ? 'X' : 'O');
return (
After applying these changes, you should have this Board component:
class Board extends React.Component {
constructor(props) {
super(props);
this.state = {
squares: Array(9).fill(null),
xIsNext: true, };
}
handleClick(i) {
const squares = this.state.squares.slice(); squares[i] = this.state.xIsNext ?
renderSquare(i) {
return (
<Square
value={this.state.squares[i]}
onClick={() => this.handleClick(i)}
/>
);
}
render() {
const status = 'Next player: ' + (this.state.xIsNext ? 'X' : 'O');
return (
<div>
<div className="status">{status}</div>
<div className="board-row">
{this.renderSquare(0)}
{this.renderSquare(1)}
{this.renderSquare(2)}
</div>
<div className="board-row">
{this.renderSquare(3)}
14 of 23 03/04/2020, 20:27
Tutorial: Intro to React – React https://reactjs.org/tutorial/tutorial.html
{this.renderSquare(4)}
{this.renderSquare(5)}
</div>
<div className="board-row">
{this.renderSquare(6)}
{this.renderSquare(7)}
{this.renderSquare(8)}
</div>
</div>
);
}
}
Declaring a Winner
Now that we show which player’s turn is next, we should also show when the game is
won and there are no more turns to make. Copy this helper function and paste it at
the end of the file:
function calculateWinner(squares) {
const lines = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6],
];
for (let i = 0; i < lines.length; i++) {
const [a, b, c] = lines[i];
if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
return squares[a];
}
}
return null;
}
Given an array of 9 squares, this function will check for a winner and return 'X', 'O',
or null as appropriate.
We can now change the Board’s handleClick function to return early by ignoring a
click if someone has won the game or if a Square is already filled:
handleClick(i) {
const squares = this.state.squares.slice();
if (calculateWinner(squares) || squares[i]) { return; } squares[i] = this
15 of 23 03/04/2020, 20:27
Tutorial: Intro to React – React https://reactjs.org/tutorial/tutorial.html
this.setState({
squares: squares,
xIsNext: !this.state.xIsNext,
});
}
Congratulations! You now have a working tic-tac-toe game. And you’ve just learned
the basics of React too. So you’re probably the real winner here.
If we mutated the squares array, implementing time travel would be very difficult.
However, we used slice() to create a new copy of the squares array after every move,
and treated it as immutable. This will allow us to store every past version of the
squares array, and navigate between the turns that have already happened.
We’ll store the past squares arrays in another array called history. The history array
represents all board states, from the first to the last move, and has a shape like this:
history = [
{
squares: [
null, null, null,
null, null, null,
null, null, null,
]
},
{
squares: [
null, null, null,
null, 'X', null,
null, null, null,
]
},
{
squares: [
null, null, null,
null, 'X', null,
null, null, 'O',
]
},
Now we need to decide which component should own the history state.
16 of 23 03/04/2020, 20:27
Tutorial: Intro to React – React https://reactjs.org/tutorial/tutorial.html
We’ll want the top-level Game component to display a list of past moves. It will need
access to the history to do that, so we will place the history state in the top-level
Game component.
Placing the history state into the Game component lets us remove the squares state
from its child Board component. Just like we “lifted state up” from the Square
component into the Board component, we are now lifting it up from the Board into
the top-level Game component. This gives the Game component full control over the
Board’s data, and lets it instruct the Board to render previous turns from the history.
First, we’ll set up the initial state for the Game component within its constructor:
class Game extends React.Component {
constructor(props) { super(props); this.state = { history: [{ squares
render() {
return (
<div className="game">
<div className="game-board">
<Board />
</div>
<div className="game-info">
<div>{}</div>
<ol>{}</ol>
</div>
</div>
);
}
}
Next, we’ll have the Board component receive squares and onClick props from the
Game component. Since we now have a single click handler in Board for many
Squares, we’ll need to pass the location of each Square into the onClick handler to
indicate which Square was clicked. Here are the required steps to transform the
Board component:
renderSquare(i) {
return (
<Square
17 of 23 03/04/2020, 20:27
Tutorial: Intro to React – React https://reactjs.org/tutorial/tutorial.html
render() {
const winner = calculateWinner(this.state.squares);
let status;
if (winner) {
status = 'Winner: ' + winner;
} else {
status = 'Next player: ' + (this.state.xIsNext ? 'X' : 'O');
}
return (
<div>
<div className="status">{status}</div>
<div className="board-row">
{this.renderSquare(0)}
{this.renderSquare(1)}
{this.renderSquare(2)}
</div>
<div className="board-row">
{this.renderSquare(3)}
{this.renderSquare(4)}
{this.renderSquare(5)}
</div>
<div className="board-row">
{this.renderSquare(6)}
{this.renderSquare(7)}
{this.renderSquare(8)}
</div>
</div>
);
}
}
We’ll update the Game component’s render function to use the most recent history
entry to determine and display the game’s status:
render() {
const history = this.state.history; const current = history[history.length - 1
return (
<div className="game">
<div className="game-board">
<Board squares={current.squares} onClick={(i) => this
<div className="game-info">
<div>{status}</div> <ol>{}</ol>
</div>
</div>
);
}
Since the Game component is now rendering the game’s status, we can remove the
corresponding code from the Board’s render method. After refactoring, the Board’s
render function looks like this:
18 of 23 03/04/2020, 20:27
Tutorial: Intro to React – React https://reactjs.org/tutorial/tutorial.html
{this.renderSquare(5)}
</div>
<div className="board-row">
{this.renderSquare(6)}
{this.renderSquare(7)}
{this.renderSquare(8)}
</div>
</div>
);
}
Finally, we need to move the handleClick method from the Board component to the
Game component. We also need to modify handleClick because the Game
component’s state is structured differently. Within the Game’s handleClick method,
we concatenate new history entries onto history.
handleClick(i) {
const history = this.state.history; const current = history[history.length - 1
return;
}
squares[i] = this.state.xIsNext ? 'X' : 'O';
this.setState({
history: history.concat([{ squares: squares, }]), xIsNext: !this
});
}
Note
Unlike the array push() method you might be more familiar with, the
concat() method doesn’t mutate the original array, so we prefer it.
At this point, the Board component only needs the renderSquare and render
methods. The game’s state and the handleClick method should be in the Game
component.
Since we are recording the tic-tac-toe game’s history, we can now display it to the
player as a list of past moves.
We learned earlier that React elements are first-class JavaScript objects; we can pass
them around in our applications. To render multiple items in React, we can use an
array of React elements.
In JavaScript, arrays have a map() method that is commonly used for mapping data
to other data, for example:
const numbers = [1, 2, 3];
const doubled = numbers.map(x => x * 2);
Using the map method, we can map our history of moves to React elements
representing buttons on the screen, and display a list of buttons to “jump” to past
moves.
19 of 23 03/04/2020, 20:27
Tutorial: Intro to React – React https://reactjs.org/tutorial/tutorial.html
render() {
const history = this.state.history;
const current = history[history.length - 1];
const winner = calculateWinner(current.squares);
const moves = history.map((step, move) => { const desc = move ? 'Go to move
let status;
if (winner) {
status = 'Winner: ' + winner;
} else {
status = 'Next player: ' + (this.state.xIsNext ? 'X' : 'O');
}
return (
<div className="game">
<div className="game-board">
<Board
squares={current.squares}
onClick={(i) => this.handleClick(i)}
/>
</div>
<div className="game-info">
<div>{status}</div>
<ol>{moves}</ol> </div>
</div>
);
}
For each move in the tic-tac-toes’s game’s history, we create a list item <li> which
contains a button <button>. The button has a onClick handler which calls a method
called this.jumpTo(). We haven’t implemented the jumpTo() method yet. For now,
we should see a list of the moves that have occurred in the game and a warning in the
developer tools console that says:
Picking a Key
When we render a list, React stores some information about each rendered list item.
When we update a list, React needs to determine what has changed. We could have
added, removed, re-arranged, or updated the list’s items.
to
<li>Ben: 9 tasks left</li>
<li>Claudia: 8 tasks left</li>
<li>Alexa: 5 tasks left</li>
In addition to the updated counts, a human reading this would probably say that we
20 of 23 03/04/2020, 20:27
Tutorial: Intro to React – React https://reactjs.org/tutorial/tutorial.html
swapped Alexa and Ben’s ordering and inserted Claudia between Alexa and Ben.
However, React is a computer program and does not know what we intended.
Because React cannot know our intentions, we need to specify a key property for
each list item to differentiate each list item from its siblings. One option would be to
use the strings alexa, ben, claudia. If we were displaying data from a database, Alexa,
Ben, and Claudia’s database IDs could be used as keys.
<li key={user.id}>{user.name}: {user.taskCount} tasks left</li>
When a list is re-rendered, React takes each list item’s key and searches the previous
list’s items for a matching key. If the current list has a key that didn’t exist before,
React creates a component. If the current list is missing a key that existed in the
previous list, React destroys the previous component. If two keys match, the
corresponding component is moved. Keys tell React about the identity of each
component which allows React to maintain state between re-renders. If a
component’s key changes, the component will be destroyed and re-created with a
new state.
key is a special and reserved property in React (along with ref, a more advanced
feature). When an element is created, React extracts the key property and stores the
key directly on the returned element. Even though key may look like it belongs in
props, key cannot be referenced using this.props.key. React automatically uses key
to decide which components to update. A component cannot inquire about its key.
It’s strongly recommended that you assign proper keys whenever you
build dynamic lists. If you don’t have an appropriate key, you may want to
consider restructuring your data so that you do.
If no key is specified, React will present a warning and use the array index as a key by
default. Using the array index as a key is problematic when trying to re-order a list’s
items or inserting/removing list items. Explicitly passing key={i} silences the
warning but has the same problems as array indices and is not recommended in most
cases.
Keys do not need to be globally unique; they only need to be unique between
components and their siblings.
In the tic-tac-toe game’s history, each past move has a unique ID associated with it:
it’s the sequential number of the move. The moves are never re-ordered, deleted, or
inserted in the middle, so it’s safe to use the move index as a key.
In the Game component’s render method, we can add the key as <li key={move}>
and React’s warning about keys should disappear:
const moves = history.map((step, move) => {
const desc = move ?
'Go to move #' + move :
'Go to game start';
return (
<li key={move}> <button onClick={() => this.jumpTo(move)}>{desc}</button
</li>
);
});
21 of 23 03/04/2020, 20:27
Tutorial: Intro to React – React https://reactjs.org/tutorial/tutorial.html
Clicking any of the list item’s buttons throws an error because the jumpTo method is
undefined. Before we implement jumpTo, we’ll add stepNumber to the Game
component’s state to indicate which step we’re currently viewing.
Next, we’ll define the jumpTo method in Game to update that stepNumber. We also set
xIsNext to true if the number that we’re changing stepNumber to is even:
handleClick(i) {
We will now make a few changes to the Game’s handleClick method which fires when
you click on a square.
The stepNumber state we’ve added reflects the move displayed to the user now. After
we make a new move, we need to update stepNumber by adding stepNumber:
history.length as part of the this.setState argument. This ensures we don’t get
stuck showing the same move after a new one has been made.
22 of 23 03/04/2020, 20:27
Tutorial: Intro to React – React https://reactjs.org/tutorial/tutorial.html
Finally, we will modify the Game component’s render method from always rendering
the last move to rendering the currently selected move according to stepNumber:
render() {
const history = this.state.history;
const current = history[this.state.stepNumber]; const winner = calculateWinner
If we click on any step in the game’s history, the tic-tac-toe board should immediately
update to show what the board looked like after that step occurred.
Wrapping Up
Nice work! We hope you now feel like you have a decent grasp on how React works.
If you have extra time or want to practice your new React skills, here are some ideas
for improvements that you could make to the tic-tac-toe game which are listed in
order of increasing difficulty:
1. Display the location for each move in the format (col, row) in the move history
list.
2. Bold the currently selected item in the move list.
3. Rewrite Board to use two loops to make the squares instead of hardcoding
them.
4. Add a toggle button that lets you sort the moves in either ascending or
descending order.
5. When someone wins, highlight the three squares that caused the win.
6. When no one wins, display a message about the result being a draw.
23 of 23 03/04/2020, 20:27