Learn React by Building Simple Games: The Memory Grid
This article is one chapter from a React.js e-book I am currently writing and planning to publish by end-of-year.
When I teach React to beginners, I start by introducing them to the React API and have them build a simple browser game after that. I think this is a good introduction strategy because a simple game usually has a small state and, in most cases, no data dependencies at all. Learners get to focus entirely on the React API itself. The official React tutorial is also a simple Tic-Tac-Toe game, which is an excellent choice.
Building simple game apps beats building abstract (and todo) apps on so many levels. I have always been against the use of abstract foo-bar types of examples because they lack context and engagement. Learners need to like what they are building. They need to accomplish something at the end of each phase in their learning journey. They need to make design decisions and see progress on features they can relate to.
The Memory Grid Game
I named the game we are going to build in this article “The Memory Grid”. It is a simple memory game where the player is challenged to recall the locations of cells on a grid. When the game starts, a few cells will flash as blue for a few seconds, then the player has to recall the locations of these cells to win.
Step 1: Initial markup and style
It is a good idea to start with any known markups and styles — get those out of the way. With simple games like this one, this is usually an easy task. Just put mock static content where the dynamic content will eventually be.
To keep this article as short as possible and keep a focus on React, I will start with some initial markup and all the CSS that we need. Here is an embedded jsComplete code that you can use to start out with an empty 4x4 grid:
https://jscomplete.com/repl/?j=rkef3YoCZ
A couple of notes about this embedded code:
- I intentionally kept the list of cells flat to simplify the code. I used the power of styling to display the list of flat divs as a grid. The alternative is to use a list of lists and convert that into rows and columns, which would have complicated the code a bit. I think whenever you can use CSS to simplify JavaScript code, you should totally do so.
- I used React’s special style attribute for the width of each cell. This width value is going to be dynamic based on the size of the grid and using React’s style object will facilitate that for us.
If you want to follow along with a different development environment, the CSS that I used for the markup above is:
.grid {
border: thin solid lightgray;
line-height: 0;
margin-bottom: 0.75rem;
}
.cell {
border: thin solid lightgray;
display: inline-block;
height: 75px;
}
.message {
float: right;
font-weight: bold;
}
Step 2: Extracting components
Once we reach a good state for the initial markup and styles, thinking about components is a natural next step.
There are many reasons to extract a section of the code into a component. For our example, I would like to focus on just one reason: Shared Behavior.
A good indicator of the need for a new component is when multiple elements are going to share the exact same behavior. In our example, all grid cells will be clickable to count towards a guess and their click will trigger a UI change, thereby indicating that we should create a component to represent a single cell.
class Cell extends React.Component {
render() {
return (
<div
className="cell"
style={{ width: '25%' }}
/>
);
}
}
class Game extends React.Component {
render() {
return (
<div className="game">
<div className="grid">
<Cell /><Cell /><Cell /><Cell />
<Cell /><Cell /><Cell /><Cell />
<Cell /><Cell /><Cell /><Cell />
<Cell /><Cell /><Cell /><Cell />
</div>
<button>
Start
</button>
<div className="message">
Game Message Here...
</div>
</div>
);
}
}
ReactDOM.render(
<Game />,
document.getElementById('mountNode')
);
You might want to extract more components, maybe a StartButton or GameMessage component. While adding components like these might enhance the readability of the code, I am going to keep the example simple and use only two components: Game and Cell.
...............
Read the full article here