Learning React(1): Getting Started

reactredux

React has drawn lots of attention inside SurveyMonkey, it has been adopted by the mobile team and become the de-facto UI framework for our next generation user experience. As a backend engineer, the react and its friends are just another layer of the frontend rabbit hole. In the “Learning React” series, I will build a small, but full-fledged app with react to explore the mobile web development.

Prefix

The grand opening of the YMCA at Sammamish is probably the best thing happened in 2016: I exercise daily, diet with calorie-awareness and lost 15lb since then. In short, I recharge myself thanks to the YMCA. The YMCA schedule is merely a PDF file optimized for print, and I want to build a mobile web app, the YMCA Schedule to present the schedule data in a mobile-friendly way:

  • Native app look-and-feel
  • Offline first
  • Personalization

Design Mockup

The visual mockup is highly recommended by the react guide to decompose the monolithic UI element to many small components, more concretely,

YMCA Schedule Mockup
YMCA Schedule Mockup

The main UI has two components, the AwesomeBar and TimeTable. The AwesomeBar is an instance of the AppBar with drop-down menu to select the facility place. The Timetable renders a daily view with events. The user may swipe left and right to pick a different date.

The internal state is also clearly defined:

  • schedule data for all the places on all days of the week.
  • the facility place, aka place thereafter.
  • the date

The Big Picture

In my humble opinion, react is a typical Facebook approach to solve the problem: reuse the existing program model but abstract away the complexity and performance bottleneck with a new layer. With react, the developers no longer need to manually manipulating the DOM to reflect the state change, instead, we can just render the current state from the scratch on a virtual DOM, and delegate the visual diff optimization to the react library.

The state change is typically managed by a flux implementation, such as redux. redux defines the following concepts:

  • action, the state change MUST be triggered by an action function. It returns a plain javascript object with the action type and meta data.
  • reducer, the reducer works as a state machine, it accepts the return value of an action and current state, and infer the next state.
  • store, the store, configured with reducers, keeps the current state.

Furthermore, the react-redux binds the redux’s state management and react’s visual representation: the Provider is instantiated with a store instance to observe the state change. Under the hood, it implements the react Component interface to trigger the redraw.

Getting Started

Getting started with react and its friends are pretty overwhelming. First, we need react, react-dom, redux, react-redux. Since we are very likely to opt-in JSX and ES6 syntax for concise code, we might need configure webpack with babel to compile, bundle and hot module reload(HMR) the web app during the development. If you need to integrate existing design, you might also need the CSS process pipeline, such as css-loader, sass and postcss.

To be honest, I never fully understand how the webpack works, so I usually copy the webpack.config.js from a redux example, such as this.

A typical redux app may look like this:

  • constants/ActionTypes.js defines all action type constants. In the retrospect, I highly recommend to use the enum alias instead of string for the action type. It is much easier to catch a undefined variable during the startup than wading through the callstacks. If you have lots of actions to create, you may consider opt-in Flux Standard Action(FSA) and use redux-actions.
  • actions/index.js defines all actions which can modify the state. I am convinced that a central repository for all the actions are easier to maintain.
  • reducers define all reducer functions. It is recommended to separate the independent state change to isolated reducers for better maintainability.
  • components defines all the visual components. They SHOULD be dumb, all business logic SHOULD sit in a container.
  • containters defines all the smart components. Not only they compose multiple components, but also the business logic to deduce the control signal for rendering.

In the very first commit of YMCA Schedule, I deliberated drop the react-redux support for a minimum redux web app, — a perfect template for the minimalist.

src/index.js

import { createStore } from "redux";
import rootReducer from "./reducers";
import { nextDay } from "./actions";

const store = createStore(rootReducer);
const rootEl = document.createElement("div");
document.body.appendChild(rootEl);

store.dispatch(nextDay());
console.log(store.getState());

Let’s work on the visual part next time.