React / Redux / Express With Socket.io
Overview
The application we'll be looking at manipulates the pixel colors of an 8 x 8 matrix. The changed values are sent via Socket.io to an Express server. That server communicates with a JSON Server via Axios - so the data is stored in JSON. The user interface was built with React and Redux. Here is what the application looks like:
Under The Hood: The Server
JSON Data Format
The JSON data is an array where each object in the array represents a matrix pixel, primarily identified by a positional x, y coordinate and a color:
{
"matrix": [
{
"id": 0,
"x": "0",
"y": "0",
"color": "#23ff41"
},
{
"id": 1,
"x": "0",
"y": "1",
"color": "#f3fcff"
},
...
{
"id": 63,
"x": "7",
"y": "7",
"color": "#f3fcff"
}
]
}
JSON Server
JSON Server can be installed globally and run from the command line referencing the JSON data file (for this project the location is: socket-io-server/db/db.json):
npm install -g json-server json-server --watch db/db.json
JSON server will use host localhost and port 3000 by default (what this project expects).
https://www.npmjs.com/package/json-server
Node Express Server
The express server listens for socket.io events and interacts with the JSON server. The server emits socket.io events back to the client after successful (and unsuccessful) database operations. The events are: INITIAL_MATRIX (query and return of the full JSON matrix data), UPDATE_PIXEL_COLOR (matrix pixel color update operation), RESET_MATRIX_COLOR (all matrix pixel color update operation). The server will emit a MATRIX_FAILURE event if an error occurs during any of the operations.
Import the necessary packages including socket.io.
Import socket.io event types defined in a constants definition file.
Determine the socket.io port, JSON database file. database host and port.
Set up express server for JSON and socket.io.
The server receives a connection, listens for events (socket.on) and invokes helper functions when the events are received. The helper functions perform database interactions and emit events back to the client.
The getMatrix function gets the matrix JSON data and emits an INITIAL_MATRIX event with the data.
The updatePixel function updates a pixel's color given a pixel identifier and color. An UPDATE_PIXEL_COLOR event is emitted to all listening clients with the data.
The resetMatrix function updates the color of all matrix pixels given a color.
The source for this server implementation can be found here.
Under The Hood: The Client
The REACT client follows the "classic" container / presentation component model. The container components dispatch actions through a socket.io middleware. Socket event types are emitted to the server. The middleware listens for socket events from the server before sending on to the reducer. Non socket event types (ex: "set color") are passed through the middleware and end up back to the reducer. The reducer updates the state and this new state is accessed by components.
The MatrixContainer component dispatches two actions: INITIAL_MATRIX and UPDATE_PIXEL_COLOR.
- Each action has the following properties: event: socket.io event sent to/from the server, emit: indicates if socket.io event, handle, errorHandle: results handling action types for reducer.
The middleware will evaluate the emit property and it will submit the socket.io event to the server.
The middleware listens for server events and dispatches to the reducer accordingly.
The reducer updates the state accordingly. The state will contain an array of matrix pixels (each pixel contains: unique identifier, x y coordinates, color) and an error property for displaying server error messages.
The MatrixContainer component dispatches two actions: initialMatrix/updatePixelColor. The render function will pass the pixels array and the event handler function to the Matrix presentation component.
The Matrix presentation component will produce an 8x8 matrix of buttons from the pixels array. The event handler function property is used as each button's event handler. The color of the button (pixel) is dynamically set using the style attribute.
The ControlsContainer component dispatches two actions: setColor / resetMatrixColor. The render function will pass a color property (the selected color) and the event handler functions to the Controls presentation component.
The Controls presentation component renders two presentation components: ColorPicker and Reset. Properties and event handlers are passed down to the respective presentation components.
The ColorPicker presentation component renders an HTML5 color picker using the color and event handler properties.
The Reset presentation component simply renders a button using the event handler property.
Video Demo
Summary
This article outlines an implementation of a color matrix where the pixel colors can be manipulated over socket.io to a Node.js server accessing a json-server database. The REACT design that was used is what I like to call the classic model - using container and presentation components. The source code for this application can be found here.