📜 ⬆️ ⬇️

Building React reliable web applications: Part 1, browser prototypes

Translation of the article “Building robust web apps with React: Part 1, in-browser prototypes”, Matt Hinchliffe

From the translator: this is the first article from the series “Building robust web apps with React”.
Translations:


When I look at how the browsers and protocols on which the web works are arranged, I feel somehow anxious. There is so much that can and usually goes wrong, which makes it amazing how at least something of what we write works at all. Reliability “against all odds” comes from resiliency and backward compatibility, which are rooted in key parts of the web stack. The browser will always do everything possible to display something useful, whether it is parsing a poorly written document in which it is impossible to get dependencies, or which is obsolete for 10 years.
')
image
404PageFound contains still working sites created back in 1993.

It seems to me that this fundamental property of the web is forgotten. We, as developers, are striving more and more to meet the expectations set by other platforms. We are especially jealous of the mobile development environment, we also want to build dynamic and flexible applications. There are a lot of amazingly smart people who, right now, are creating applications that allow us to do this, now there really is a wonderful time to work in this industry. However, I do not think the current toolkit is; Angular, Ember, Knockout and others. This is what the future of browser development is about, because they are not inherently reliable.

I’m worried that I’m seeing sites that make JavaScript the cornerstone of content at the moment and for the future. This is the construction of the base on the most fragile part of the stack.
- Jeremy Keith, Time (Full Frontal 2013)

The added complexity and burden we place on the browser means that the user may not see anything, even if there is a minimal problem. This problem is not so much the above-mentioned tools, as in the modern approach of building websites; empty body tag on the page is simply not allowed . Our sites should be at least accessible when they are requested using a crappy connection or running in an old browser. We have to realize the fact that the web browser is not at all the working environment of the smartphone, because there is so much that we can not control!

image
The main Squarespace page hides all content, relying on JavaScript to handle its visibility.

I’m not here to preach the Ludit philosophy, I really don’t want to say that we have to design pages in pure HTML. We can definitely overcome the fragility that we introduce on our sites, but to do this, we need to rethink some of the techniques that we use, and for there are some interesting tools, my favorite of them, is the React library from Facebook and Instagram developers .

React is awesome because it provides a new way to build and deliver interactive interfaces. React provides simple tools for creating adaptive hybrid or isomorphic web applications. Initial HTML can be generated on the server (without any brainless browser tricks) for React to be reasonably presented after loading the browser.

React is not an MV-whatever framework, it only handles the 'presentation', but not the usual patterns. React views are not just pieces of text that need to be dumped onto the page, this is a lightweight, intermediate representation of the DOM, a technique better known as the “virtual DOM”.

Using an intermediary, instead of reading and modifying this model of the document, allows the difference algorithm to count the least number of steps necessary to redraw the state. This is combined with other productivity-accelerating things, such as a sensible delegation of events and batch DOM updates, and makes React amazingly fast.

React allows applications to be written expressively – interactive by default, but also returns reliability to dynamic websites. This is reasonable and makes only a small, if any, fine in performance.

Sample application


An example I’m going to create is a dispatch board for London Underground stations using the TrackerNet API or “Tube Tracker”, for short.

image

This application has only four states: the display of greetings, download or error message and the display of sending trains from the station. For a certified production level developer, an application can be represented by the following diagram:

image

Instead of going through the process of writing an application line by line, I will explain a few basic things and processes that are useful when you first use React.

The TrackerNet API is a product of the past era, it is poorly documented and lacks data on stations and entire branches. Problems with TrackerNet were well described by Chris Applegate and solved in his open source project When's My Transport . Fortunately, it seems that its old API will be replaced soon .

Fast browser prototyping


React applications can be quickly prototyped in the browser without any preparation. I prefer to write my components using the optional JSX syntax, which will allow them to be written very similar to the HTML syntax. If it seems to you that embedding HTML in JavaScript is wrong, this can be understood, given the years of their separation, but for me it turned out to be a more productive approach, and it makes visualization easier than using pure JavaScript. Connecting a React and JSX Transformer (available on Facebook CDN) is all you need to get started:
<html> <head> <title>My React App</title> <script src="http://fb.me/react-0.9.0.js"></script> <script src="http://fb.me/JSXTransformer-0.9.0.js"></script> </head> <body> <script type="text/jsx"> /** @jsx React.DOM */ </script> </body> </html> 

Setting the type attribute of the script element to anything other than text/javascript allows non-JavaScript data to be embedded on the page. Since the script element is not intended for the user, it does not have a visual display on the page.

Component Hierarchy


React applications are assembled from components organized into a hierarchy. The easiest way to plan the application architecture is to work out the responsibilities for each part of the interface and draw blocks for them. Ideally, each component should process only one thing , so that the complex components are divided into smaller sub-components.

image

Our framework can be organized into the following hierarchy:

Properties and condition


React has two types of data; “Properties” passed between components and “state” that is stored inside the component. A component can change state, but its properties do not change, which is good, because, ideally, there should be only one source of truth. A key architectural solution when designing a React application is deciding what data is required by each component and where it should be the source.

image

Tube Tracker requires only three types of data: network data (lines, stations, etc.), a line and station selected by the user, and schedule data received from TrackerNet.

These networks are consumed only by the Network and Line components to provide station lists, as well as the TubeTracker component for validating user input. This is a large amount of data, so it is better to process them externally and then transfer them to the application.

The line and station selected by the user are used by the Predictions component, but the selected conditions are provided by the Line component. Following the hierarchy of components, their common ancestor is TubeTracker, so the selected line and station must be stored in the state of the TubeTracker component.

Finally, TrackerNet forecast data is used by the Trains , DepartureBoard and Predictions components, but not by the TubeTracker component, so they must be stored in the Predictions component.

But there is a problem; data must be passed back up the hierarchy. When a user input is received by a Line component, his ancestor, TubeTracker needs to know about it.

Thinking in React (Thinking in React) - a more detailed overview of the hierarchy of components and the differences between properties and state, it is definitely worth reading.

Component Communication


Since data can only be transmitted down the hierarchy, we must use another technique to transfer data up. There are two main ways to do this.

If a component should only transfer data to its forward ancestor, then providing a callback is the simplest solution. React automatically binds the component's methods to each instance, so there is no need to worry about passing context.

 var Parent = React.createClass({ handleClick: function(e) {...}, render: function() { return <Child callback={this.handleClick} />; } }); var Child = React.createClass({ render: function() { return <a onClick={this.props.callback}>Click me</a>; } }); 

For more distant notifications, the publish / subscribe system (publish / subscribe) will be more flexible and easier to maintain. This can be done by native JavaScript events or by using the PubSubJS library, by binding to the component's lifecycle methods.

 var Parent = React.createClass({ handleMyEvent: function(e) {...}, componentWillMount: function() { window.addEventListener("my-event", this.handleMyEvent, false); }, componentWillUnmount: function() { window.removeEventListener("my-event", this.handleMyEvent, false); }, render: function() {...} }); var Grandchild = React.createClass({ handleClick: function(e) { var customEvent = new CustomEvent("my-event", { detail: { ... }, bubbles: true }); this.refs.link.getDOMNode().dispatchEvent(customEvent); }, render: function() { return <a ref="link" onClick={this.handleClick}>Click me</a>; } }); 

Component life cycle


Components have a short API to hook on their life cycle; creation (mounting), updating and destruction (unmounting). Unlike other approaches for building dynamic interfaces, this functionality is built into the component definition. In the example of component communication, I used the componentWillMount and componentWillUnmount methods to add and remove event handlers, but there are other methods that give detailed control over the properties and state of the components. In the Tube Tracker application, I also used the following methods:


Here is what I did before


So, we installed a browser environment, broke our UI into components, found out what data we need, where they should be stored and how they are distributed in the application, it's time to demonstrate!

image

I used Express to install a small HTTP server to roll out static files that will be used in the following parts of this article series. You can try the app right now (note: the example is running on a free account, so this link may be unstable) or go to GitHub to view the source code .

In the second part I will describe the optimization of the application; installation of code optimization tools for the browser. Please comment or tweet me , I will be happy to receive feedback.

Source: https://habr.com/ru/post/229655/


All Articles