In this series of blog posts, we’re looking at how to set up a simple web app in node.
In the previous installment we looked at building an API in node, and then consuming it from a web app using browserify to build node modules into a JavaScript file for the browser.
In this post we’ll look at using react to render the data on the screen.
Installing dependencies
We’ll need a couple more modules, lets install react, and reactify (which allows browserify to build react components).
Creating a react component
React is a JavaScript library from Facebook for rendering user interfaces in the browser. It’s not a full feature framework (like Angular), instead it’s designed to handle the redrawing of UI components in response to changes in a data model. It takes the controversial decision to combine together logic and markup into reusable components. React also allows you to use JSX, which is a JavaScript where HTML is treated as a first-class concept. This can take a bit of getting used to. I like React. It’s a pleasure to work with, and I’ve found the re-usability of components very useful.
Now lets create a new JavaScript file in our client
directory, to hold the react component to render our todos. Let’s call the file todo-list.js
.
The file will return a react component, using the node style module.exports
variable, like this:
There is a lot going on there, lets break it down.
- On the first list we
require
react. This allows us to create react components. - We then call
React.createClass
to create the react component, and export it on themodule.exports
variable. This allows other files torequire
this one, and use the component. - The component has a
getInitialState
function, which returns an initial state for our component. We’re using state to track the current value for the new todo that a user is entering. We’ll return a state where the text is an empty string. - The
handleSubmit
function handles the form post when a new todo is created. It calls aonNewTodo
function that must be set on the component when it’s used. It also resets the text to empty. - The
update
function is called when the user types into the text box, we’ll update the state accordingly. - The
renderTodo
function is called to render each todo. It returns the angle brackets to show the todo. Note that theonClick
event for the delete button is bound to anonDelete
function which must also be passed to the component. - Finally we render the main page, calling the
renderTodo
function for each of the todos. We also bind theupdate
function to theonChange
event for the text box, so it can update the state as we type.
Ideally this component should be broken down into separate components: one for the todo list, and another with form for adding a new one. In the interests of simplicity I’ve kept them together.
Connecting the API
I have made the intentional decision not to call the API directly from the react component. Instead, I pass in functions which are called by the component when data needs to be saved/deleted. This separates out the concern of the data loading from the rendering, allowing us to re-use the component, or test it in isolation.
We therefore need to connect the API up with the component, to do this we’ll rewrite the index.js
file:
The index file now has functions to call the API for adding and deleting todos. The render
function gets all the todos from the API, and renders our react components, passing in the data from the API, as well as the functions which call the API. The render
function gets called immediately, to show the component on application startup. The render function is also used as the the callback when todos are created/deleted on the API.
That’s all we need to do for now. We can build the react components by changing our command slightly to this (remember the reactify
module we installed?):
You can start the application as before with:
The application should appear the same, only this time it’s a SPA!