Minesweeper is a well-known and quite popular computer game from the 90's. For the purpose of this article I decided to revive it in ReactJS technology.
The best practice when using ReactJs is to create a hierarchy with one master component on the top. That component presents the application itself and holds the global state of the application. In MVC architecture, that component will be used as a controller and will handle changes on a model state, triggering a rendering when necessary.
Creating a good model is a key step in developing any good application. Model will hold the data that represents the application's current state. Each object should represent one specific element and should only contain at least outer dependency as necessary. A simpler model allows you easier data handling when changes occur.
View is implemented by creating low-level React components that can be reused in multiple places in application. Each view component always represents a single model object and it contains that object as a property of a view. Each view component is also responsible for catching HTML events and forwarding them to controller. In order to handle such events from input devices, each input device is also represented in model. In Minesweeper case it is the MouseModel that holds informations about current mouse state and alerts controller when actions are made.
Image 1: Minesweeper – Architecture
Handling State Changes
Controller contains the whole global state of the application. It reacts on state changes of input devices, delegates actions to a game model, and updates application state when necessary. In order to be able to update application state, the controller must be aware of any state change on the model. For that purpose, the "event listener" pattern is implemented on model.
Each model component implements an interface that contains two methods: addEventHandler(eventHandler) and fireEvent(eventName, event). Each model object sets an event handler callback to each of its children. So, when model object changes its state it can fire a "stateChanged" event. Its parent will handle that event and fire the same event to its parent and so on and so on, until the event reaches the controller on top of the hierarchy. Controller then handles that event by updating global state and starting render() procedure that will update the view.
Image 2: Minesweeper – handling state changes
This application was created as a full front-end application and requires only a browser to run. It was developed for the Chrome browser and was not additionally adapted to other browsers. It was developed as a full front-end, but it also offers an option of adding a scoreboard that requires a back-end REST service with some kind of persistence.
A live demo is available on: http://dobilinovic.comsysto.com/minesweeper/
And, the source code is available on gitHub: https://github.com/Obee88/minesweeper-react