Monday, September 19, 2016

React: Controlling state to accelerate development

I first started looking at the React JavaScript library from Facebook in early 2014. I had previously worked on sites using MVC frameworks like Angular and Backbone and at first it was hard to see what problem React was trying to solve. The other frameworks had an API for templating and even HTTP calls, but React could only render HTML in the browser. When I dug into the design it soon became clear what the goal of React is. It controls the amount of state required to render UI elements and it allows developers to create components with a single responsibility that can be safely composed into a whole system. The following is a high level overview of how React achieves this.

How React controls state

The core principle of React is to control and encapsulate the state of the user interface. React components do this by exposing two objects, Props and State.

Props

Props are supplied by a parent component to the children it creates. The props object is set at the time the component is created and it never changes, therefore it is immutable. This enforces one-way data binding so that an element, for example an input control on a form, can be populated with a value held in the props object.

However, when the user changes the value in the input field it will not change the value from the props object that it is bound to. The advantage of this is that values in the props object can be safely used anywhere in the UI and we know that they will not change the state of the application. The only place they can be changed is in the component that owns the original state. Components that only use props are stateless which means their behaviour is derived from the inputs given to them.

State

State is an object of a component and it is private to the component. The state can only be shared with child components by passing the values as props. The children can not change the state, only render it. If a child does need to mutate the state of the parent, the parent component provides a callback function in the props object. This allows the parent to decide how and when it will mutate the state. This builds upon the one-way data binding model into a one way data flow model for the application. With React, the user interface is composed of mainly stateless components with some stateful parent components controlling how state changes. With this model, the data flows down the tree of components and messages flow back up the tree in the form of callback functions to trigger state changes.

How React applies functional programming

The design of React is heavily influenced by principles common to functional programming. In fact the first prototype of React was created in OCaml. Stateless components are essentially pure functions and the encapsulation of the mutation of state is a core tenant of most functional programming languages. The building of a user interface by composing smaller components together in React is the same as function composition in functional programming. I am pleased to see the principles of functional programming forming the basis for a very popular library, as I believe that they lead to safer software that is quicker to develop.

Conclusion

React brought the principles of functional programming to the JavaScript ecosystem. It also captures a view that I have that software should be developed so that state is never changed in more than one location. I have seen many applications become brittle and impossible to extend because state is being changed in a number of places. The change becomes difficult because all the points of mutation must be found and checked to see that they still work with the change being made. A single point of mutation makes this problem go away.

React has now reached a point of maturity where the API has stabilized as have the supporting tools like Redux and react-devtools. It is the tool I now choose to build new web applications. It forces me to think up front about all the components I need for the user interface and which ones will hold state and which ones can be stateless. For more information look at Pete Hunt’s great post or try React using the new create react app tool.