I have avoided larning React for a long time, partially because I don't use it in company projects (we use homegrown stack) and partially because I was telling myself that it was yet another framework I could easily learn when I need it.
Now I have decided it's time for me to learn different stack altogether and to bring myself up to speed on all new tools. So in the next few posts you can expect to see more about react, nodejs and postgresql.
Where to start?
Every time when I test new library/framework I try to find good starting point for creating new application. In JS world when you start new project you need to think about tool-chain you will use. Do you want to use some kind of transpiling (typescript, babel), bundling, minification, dev server, hot reload...
It really becomes overwhelming if you do not have some kind of guidance of best practices for given framework. For React I was completely blown away by Create React App. By executing following command I was able to get up and running in under a minute:
npx create-react-app my-app cd my-app yarn run start
When you run this command React tooling creates for you sample application with toolchain already set-up. Right away you have development server up and running with hot reload and webpack is completely transparent, you can only use npm (or yarn) to do start and build. Amazing!
To set-up project which uses typescript you would use following command:
npx create-react-app my-app --typescript
Simple and right to the point.
Maybe the hardest thing with React applications is to create proper structure of components. To decide whether component is stateless or statefull and which component should hold state.
I have found a good post that describes this process in detail here.
For the Minesweeper game I have decided to structure it in following way:
- Square component - Represents a basic square in the board. This component is stateless only has props and its job is to add correct classes to button element and to handle events.
- Board component - Again stateless component that gets array of squares it needs to render. Its job is to render squares properly and to handle events.
- Game component - This is statefull component that keeps track of various game elements such as board, stats, levels. All events on Square and Board are propagated to Game component which has the main game logic.
The main idea in this React application is to listen to click event on Square (I call it Reveal in code) and then we mutate list of squares and React can figure out what to update on screen.
I had to change reveal code to be more inline with React recommendations to make state immutable, and to update state only when needed. Because of this I had to create "revealInternal" method that could work recursively on squares, and to mutate state only when everything is finished.
Of course there is more to it than that but if we look at it from the React perspective this is all that it's doing.
In my github repo you can find commented code with explained logic behind initializing board (planting mines and calculating distances), revealing square (regular and auto mode), flagging square, timer, stats and more.
I'm really satisfied with the result application. Development experience has been great, I could focus on coding the actual game instead of trying to figure out how to configure tool stack.
I think that React is really suitable for this kind of games because it can efficiently calculate exactly what needs to be updated in DOM (using its virtual DOM feature) and to make minimal updates.