Part of Celerity’s commitment to clients is ensuring we always stay up to date with the newest tools and technologies as they come out in order to provide exceptional near-shore software development, among other services. Right now, React is that new, hot tool – mainly due to Facebook using it for everything and the open source community running wild with it.
As an open source developer for our digital experience, or digital strategy consulting, team, I’ve mostly worked with Angular over the past few years, but I wanted to check out React and Flux to see how it compared to Angular for creating SPA architecture (Single-Page App).
The main goal for this research was to use the most up-to-date development techniques and explore their viabilities for future projects. Some of these include the ability to:
- Use React with the Flux architecture to create a single page application
- Use Webpack to manage module loading between files
- Write all rendered react code using JSX
The Transition from Angular to React
The underlying philosophies between React and Angular are vastly different. Angular promotes itself as a full solution for a SPA architecture with models and views synced using two-way data binding.
React takes a more functional approach using the idea of component composition. A view is made of React components. The library itself is composable to create a full SPA solution. React aims to just handle how the view is rendered with other libraries handling how data is synced.
Flux/Angular MV* flow
When transitioning to the Flux architecture, forget about two-way data binding. The fundamental idea behind React is managing state and to do this, Flux utilizes one way data flow. This paradigm takes a while of writing an application before you get that “aha!” moment, but once you do, everything else about React and Flux falls into place. Read more about Flux on their official page.
Boilerplate template code
During the course of my deep dive into React I was able to put together a React/Flux boilerplate that takes into account best practices and up-to-date standards used by the community:
- JSX files end with .jsx as recommended by the react team, to support tooling.
- Write idiomatic ES6 wherever possible to take advantage of awesome features, such as fat arrows for maintaining proper scope.
- Use Reflux.js to simplify flux data flow.
- Test using Jest. Mocking of libraries was always one of the most annoying thing about setting up testing files. Jest automatically mocks external libraries.
- Maintain a module project structure where all files associated with a feature are contained within the same directory
- Use a CSS preprocessor and allow easy swapping of major three: SCSS, LESS, and Stylus
- Use Webpack for easy module bundling and loading
- Use Gulp for builds and allow configurations for switching easily between dev builds and production builds
The Boilerplate Template can be found here.
During the React exploration I created two simple apps, which search github for a user, then retrieve the closest matching user’s repositories. The first app uses the React template starting point and the second app is created with Angular using the ng-poly generator.
Angular Demo source: https://github.com/celerityweb/blog-react-flux-angular
React Demo source: https://github.com/celerityweb/blog-react-flux
Below I go through a full data flow cycle for both an Angular application and a React/Flux application.
Input and Handlers:React Version
Above we see JSX defining a form, and relevant controls. In this component, we also define the handler that is called for both submit and click events on this form. When called, the defined handler simply fires off a user search action (more on that later).Angular Version
We define our form and relevant controls in an html template. We bind the search input field to its respective model and bind the click and submit handlers to the corresponding function in the controller. This controller function then calls our service for making the relevant API call.
Using Reflux, a list of actions can be defined as above.
The Data store, as seen above, listens for this action to be fired off and makes the appropriate request to our API.
A component can then in turn listen to one or multiple data stores. Reflux.connect is a mixin to sync the component’s searchResults state with the Store’s state and re-render the component when necessary.
In the Angular version, we would define a factory or service that calls our API.
When the API returns successful, update the model values with the returned values.
These values are then populated in the template.
The community support backing React and Flux is huge right now, which may or may not be a good thing. When investigating Flux abstractions a simple search revealed 9 different implementation of Flux.
My overall findings and preferences:
- React definitely promotes a better SPA architecture style, but at the expense of more boilerplate.
- React forces components to remain dumb and never manipulate state directly.
- In Angular, it’s too easy to write directives that rely on the state of other components.
Overall I would use a React/Flux architecture for a vastly different use case than Angular. In cases where I have a lot of inter-component communication or manipulation, need server side rendering, or have to pass data to thousands of elements, I would prefer React and Flux.
In cases where I need a single page app with a ton of two way interactions, I would prefer Angular.
If you’ve had different experiences with React/Flux, I’d love to hear about them. You can post a comment below.