I’ve been working with React a bit lately and wanted to document my experience and findings. Since there’s quite a few “hello world”/getting started guides out there already, I’ll provide links to those and cover key points I took away from articles and experience.
When React was announced around mid-2013, it looked like an interesting concept and seemed like it should be pretty significant considering it was being maintained by Facebook. However, it fell off my radar soon after. as It was too early to use in any of my projects. Looking at where React stands now in addition to supporting libraries, I can see that the scene has matured and stabilized quite a bit.
What is React?
React is a JavaScript library created by Facebook that fulfills the functionality of the view in MV*C. It stands by itself and aligns with the “single responsibility” principle that is the first of the five S.O.L.I.D object-oriented programming and design principles. Other concerns such as routing, controller, and model/stores are separate patterns that exist outside of React.
Because of this separation, React can fit into other frameworks or be pieced together with other libraries to make a complete MV*C framework, such as Flux (see which Flux implementation should I use on history/development of Flux), Redux, or Cerebral.
React is designed to be scalable and fast. Some patterns like its root level event listener are intended to make React fast, and other features, such as the virtual DOM, use encapsulation to reduce or eliminate common problems with scaled web applications caused by conflicting class/ID names and DOM manipulation side effects.
Also worth noting, React was split into react-dom and react-native to independently support browser and mobile apps. For this article, I’ll be covering what is referred to as react-dom, which is React for the browser.
Learning Curve
Working with React and its ecosystem has been interesting. Given you’re already familiar with JavaScript, React itself isn’t that difficult to comprehend. Though it does take some time to understand the concepts React is founded on and what problems it is addressing. For example, the data flow design may take some time to get used to.
The challenges with React more lie in the ecosystem, when third-party libraries and the build process come into play. However, the libraries are worth getting familiar with, and the build process should become less confusing as things settle down. For now, there are plenty of boilerplate start projects on github.
Getting Started
The first step is to take it easy and not get overwhelmed. There are a collection of technologies that make a React stack, and they don’t have to be learned at once, I recommend first focusing on React and JSX first. By understanding the core concepts and working with plain React is a good start.
React’s homepage goes over the fundamentals of building a React app from scratch without diving too far into the tool chain. A starter kit can be downloaded from their getting started guide.
Most examples require compiling the HTML like markup called JSX into JavaScript. This can be done through a browser version of the Babel library called Babel Standalone. However I’ve found this makes debugging difficult, because I can’t set accurate breakpoints. Compiling the application outside of the browser as part of the build process is recommended.
The following is a simple “Hello World” component defined with a pure function. For components that don’t hold state (covered further down), pure functions are preferred over react factories, such as React.createClass or React.createComponent.
See the Pen React Hello World by Justin Osterholt (@hattraz) on CodePen.0
One-Way Flow Design
React uses a unidirectional data flow design that enforces immutability. This means data flows down from parent to child, and children cannot directly mutate (change) the parent’s data. A core reason behind this design is to avoid side-effects that could be caused by children components and other library functions.
All changes are made through a store in one way or another, and those stores send out a change event which is then used by the view to rerender the view. The following is a diagram that represent React with the Flux framework. Despite having the additional framework, this still shows how the data flows throughout the applications life cycle.
This design allows React to efficiently update the UI without needing to re-render components that haven’t had any data change. In addition, for more complex apps that rely on state change events, event handling is simplified, and cascading updates are avaoided.
For a more comprehensive look on how React fits into an application with diagrams and other insight to boot, I suggest this read by Adam Neary.
And as a side note, Immutable.js is a popular library for handling immutability in JavaScript.
Components
In React, the UI is broken up into a collection of components and subcomponents. Both are represented by the React component class, which are a core part of the library. Components objects contain props, state, and functions. Props and state are both types of data the object holds, but they have a different purpose and set of rules. As a rule of thumb, it is encouraged to use props over state.
Props
Props are the more common data type used to populate components dynamically. Data assigned to props is passed into the component from its parent. They are also immutable, meaning they are read-only and cannot be written to. This stays consistent with the one-way flow described earlier.
See the Pen React Props Sample by Justin Osterholt (@hattraz) on CodePen.0
State
State data is the component’s own private locally scoped state, it is not shared with the parent or child components. State is set during component initialization and persisted throughout the components life. Unlike props, state is mutable, meaning it can be changed, though mutation is accomplished through the setter function, setState.
See the Pen React Sample by Justin Osterholt (@hattraz) on CodePen.0
When to Use State
Try to keep as many of your components as possible stateless. By doing this you’ll isolate the state to its most logical place and minimize redundancy, making it easier to reason about your application.- “What Components Should Have State?“
State in components is a little confusing, because it’s there to be used, but only under certain conditions.This is because application state, which is used by other components and sometimes persisted to a database, is meant to be kept in state stores, which live outside of the components.
Best practices encourage state to be used minimally and not to use anti-patterns, such as manipulating props in getInitialState.
JSX
React introduces markup called JSX which is akin to a templating language and looks like HTML markup. What you’re actually working with are React components that represent HTML elements and components.
For example in the props example, the following JSX:
<App title="Some Value" customClass={someVariable} />
is “transformed” into JavaScript like so
React.createElement(App, { title: "Some Value", customClass: someVariable })
React.createElement returns a ReactElement object, not an HTML element that is used in the browser DOM, as document.createElement would return.
For further reading on JSX, I suggest JSX Looks Like an Abomination by Eric Elliott.
Virtual DOM
The React website describes the what the virtual DOM is and what benefits it provides clearly:
React abstracts away the DOM from you, giving a simpler programming model and better performance. React can also render on the server using Node, and it can power native apps using React Native.
The virtual DOM is a tree structure composed of ReactNodes that are rendered into the “normal” DOM. ReactNodes consist of ReactElements, strings, numbers, and arrays of ReactNodes.
To get more into the details of the virtual DOM, I suggest reading “The difference between Virtual DOM and DOM“. But an in-depth understanding of how the virtual DOM works isn’t needed to get started.
Conclusion
React is a maturing JavaScript library with a passionate following of web developers. Its decoupling from other concerns, such as controller and model, allow it to be flexible and focused on displaying data within the view. It utilizes several practices that results in cleaner and more efficient code, such as one-way data flow and only rendering components that have been affected by a state change.
React is a good consideration not only for scable applications, but anything that can benefit from the automatic update of the view on state change or the immutable data store design. This could include something as simple as an e-commerce page with a product list and shopping cart.
Immutable data structures may be met with some apprehension, but it encourages mutating data in a single location (the store), which is more predictable and avoids side effects. Besides, view is meant for displaying data, not handling changes.
When compared to other frameworks like Angular, React will seem incomplete, but this is because React is only focusing on one part of the architecture. There are plenty of third-party libraries that are ready to take on the responsibility of router, controller, and model/datastore.
For more information, there’s also a list of helpful JavaScript links here and video on RS Conf.