Create a Memory Game with Next.js
Cover photo by Dan Mall on Unsplash
As new technologies and frameworks evolve, we start to get curious about it. When we first get contact with very early stage ones, eventually we could get the wrong idea about it as their concepts are not fully evolved and the integration and API is also not fully stable. And after those technologies grow it is possible to get a better perspective of them.
With that in mind, I wanted to experiment again with Next.js after some time since I first jot with it, some years ago. As a starting point I wanted to do something that I could use and present to others without saying “You know, it is just a test project so it won’t work for X, Y and Z”.
After some consideration, I wanted to create a simple Memory Game.
Setting up the project
I have to say that Next.js has lots of configurations out-of-the-box that were very handy, just running their own standalone app. As mentioned at their official doc, just run
npx create-next-app@latest
And their standalone will ask you things about how do you want to code and your project structure. For me, It was very handy as I wanted to use things like:
- TailwindCSS
- TypeScript
- ESLint
- React Testing Library, which is not configured by the executable, but can be easily installed and has examples at Next.js official docs
That’s it. Run the project locally with yarn dev
and access your localhost:3000
.
Creating the Page Elements
The integration between how the project is structured and how the routing works is also a plus. It is very similar to what Remix framework did (just saw there first, don’t know who started it!). It is not needed to setup a router as your “folders are your router”. That’s how it felt to me.
Then I just created the first elements, the <Board />
component and its <Card />
component to present the cards.
In order to create some “moviment” I added some transitions and control them with state out of the <Card />
component. A hook called useGame()
that is responsible for storing the logic of the game was created.
Game Logic
After creating the page elements, the logic code must be created. As mentioned before, the hook useGame()
was created and inside of it, after creating several states with useState()
I just notice that this is a use case for the useReducer()
.
export function useGame() {
const [game, dispatchGame] = useReducer(gameReducer, initialGameState);
/* ... */
return {
state: {
...game,
},
handler: {
revealCard,
reset,
}
}
}
There are some handler
s and the game state
that can be accessed by the Page and its components. The state
nformaion provided by this hook is:
- the list of
cards
(already shuffled) - the list of
found
cards - the list of
revealedIndexes
from the actual screen - and the
moves
counter
And the handlers
are:
- one callback to
reveal
a specific card based on its index - one callback to
reset
the game
The game result is decided using the util function isGameOver()
, when all cards have been found.
Final Thoughts
It was nice to understand some of the concepts used by Next.js
such as their router and the frameworkd itself. Also, how those learnings translate and impact the developer experience while creating an app made me realize that Next.js is actually a good option to bootstrap a project nowadays.
Parallel to that, it was also nice to exercise some of the ReactJS
knowledge and how to test it using React Testing Library
+ Jest
.
The final project to be live-tested at memory.caian.dev, and the code is provided at this GitHub repo.