In a previous post, Facebook’s React, and the Signal:Noise Ratio, I looked at where React fits in amongst its rivals.

Firstly: why use Redux?

Many developers who have had some experience using React over the last year or two will most likely have been using one of the libraries that implements the Flux pattern – so why use something different?

Dan Abramov, author of Redux, provides a very useful set of reasons for using Redux. TL;DR:

Reducer composition: reuse functionality across stores

reuse functionality across stores Server rendering: simplifies enabling of server rendering

simplifies enabling of server rendering Developer experience : makes it possible to change reducer code on the fly or even “change the past” by crossing out actions, and see the state being recalculated

: makes it possible to change reducer code on the fly or even “change the past” by crossing out actions, and see the state being recalculated Ecosystem: Redux has a rich and fast-growing ecosystem

Redux has a rich and fast-growing ecosystem Simplicity: Redux preserves all the benefits of Flux (recording and replaying of actions, unidirectional data flow, dependent mutations) and adds new benefits (easy undo-redo, hot reloading)

What’s covered in this codebase?

We have tried to anticipate the requirements of developing a typical React app, while avoiding producing a bloated codebase. Here’s a quick look at the home page:

Routing

We are using react-router as the routing library, along with react-router-redux to keep react-router and redux in sync. These allow us to exploit redux-devtools (more details below).

Development tools included:

redux-devtools – a live-editing time travel environment for Redux

– a live-editing time travel environment for Redux webpack , configured with: webpack-dev-middleware and webpack-hot-middleware react-transform-hmr and babel-preset-react-hmre CSS Modules, which provide auto-namespaced CSS styling, accessible from Javascript .eslintrc pre-loader production and development builds based on NODE_ENV

, configured with:

It’s also definitely worth watching Dan Abramov’s React Europe 2015 talk on Hot Reloading with Time Travel.

Language

We have included the use of some recent advances in Javascript development:

Flow – strong typing for Javascript (!)

Babel, allowing ES2015 (aka ES6) development, and beyond – exciting new JS standards

So we can now write code like this simplified version of ProfileEditPage.js :

import React, { PropTypes, Component, Element } from 'react'; import { FormattedMessage } from 'react-intl'; import { User } from 'declarations/app'; import ProfileEditForm from 'containers/ProfileEditForm/ProfileEditForm'; import { updateUser } from 'redux/modules/user/user-actions'; import { autobind } from 'core-decorators'; import { connect } from 'react-redux'; import { messages } from './ProfileEditPage.i18n'; export class ProfileEditPage extends Component { static propTypes = { dispatch: PropTypes.func.isRequired, user: PropTypes.object, }; @autobind handleUpdate(user: User) { this.props.dispatch(updateUser(user)); } render(): Element { return (); } } const mapStateToProps = (state) => ({ user: state.user, }); export default connect(mapStateToProps)(ProfileEditPage);

There is also a set of ESLint code-styling rules based on the AirBnB rules.

Design

It can be difficult to choose which design library to use, but it would appear that Twitter’s Bootstrap currently has a broad uptake, so the project uses the react-bootstrap Bootstrap components for page layout, menus and a form; it is also built responsively:

Internationalisation

We are assuming that making a website available in more than one language is very often a requirement of a modern website, so all content has been rendered in English and Spanish using react-intl .

Build

As well as a development build incorporating hot module reloading and live-editing time travel, there is a sample production build:

$ npm run start # development build; point browser at http://localhost:3000/ $ npm run build # production build

Simulated Login

Selecting the right-most menu item simulates a user login; implementation of actual login is left to the developer.

Restricted Pages

Once you have logged in, a menu option for another page is available, along with a link to log out:

Check src/routes.js for examples of how to restrict certain routes to only be available when the user is logged in.

Forms

Development of HTML forms for Redux requires a rethink in terms of approach to development. We have used redux-form for form integration with Redux, and redux-form-validation for validation:

Containers vs Components

A naming convention seems to be emerging in the React community that allows us to distinguish between a stateless reusable component (“component”), and one that is dependent on state (“container” or “container component”). To this end, the directory hierarchy is separated into components and containers directories.

As an observation, an iteration pattern while developing often goes like this:

build a component to accomplish a piece of functionality

realise that it is stateful, and could be split

divide it into two: a thin container that handles state (fetching data, for example), which is wrapped around, and provides data to, a stateless component

Michael Chan writes more about it in his Container Components post.

Unit Testing

Some simple unit tests have been included that demonstrate unit testing with React and Redux. These are *.spec.js files, and reside in the same directory as the code they are testing.

Conclusion

We’ve had a lot of fun putting this codebase together. It’s available on github here: https://github.com/opencredo/opencredo-react-boilerplate

Please feel free to comment, fork the project, and contribute!

Further reading

Starting off:

Digging deeper: