React & Flux in 15 minutes

(mission impossible?)

What is React?


Only the User Interface (components)

Virtual DOM

One way reactive data flow

<Hello> pure stateless component

import React from 'react';
import ReactDOM from 'react-dom';

const Hello = ({ to }) => <h1> Hello, {to}! </h1>

ReactDOM.render(
    <Hello to="Bärner JS Folks" />,
    document.getElementById('root')
);

<Hello> pure stateless component (simpler?)

import React from 'react';
import ReactDOM from 'react-dom';

function Hello(props) {
    return <h1> Hello, {props.to}! </h1>
}

ReactDOM.render(
    <Hello to="Bärner JS Folks" />,
    document.getElementById('root')
);

<PizzaList> pure stateless component

const PizzaList = ({ pizzas }) =>
    <div>
        <h3> Pizzas </h3>
        <ul> { pizzas.map(pizza => <li> {pizza} </li>) } </ul>
    </div>

ReactDOM.render(
    <PizzaList pizzas={['Capricciosa', 'Margherita', 'Napolitana']} />,
    document.getElementById('root')
);

<PizzaList> pure stateless component (simpler?)

function PizzaList(props) {
    return (
        <div>
            <h3> Pizzas </h3>
            <ul>
                { props.pizzas.map(pizza => <li> {pizza} </li>) }
            </ul>
        </div>
    );
}

Sweet, terrible JSX


An XML-like extension to ECMAScript (JavaScript)

Transpiled into standard JavaScript

Resulting JavaScript is essentially createElement() functions

... which interact with the Virtual DOM


Separation of Concerns? Only one 'concern' here: rendering the UI!

The Virtual DOM


An abstraction that frees you from touching the DOM directly

Also good for server-side rendering

... and for automated testing!

Implements an efficient diff algorithm to compute the fastest way to update the browser

<HeartButton> stateful closed-box component

class HeartButton extends React.Component {
    constructor(props) {
        super(props);
        this.state = { hearted: false };
    }
    handleClick(event) {
        this.setState({ hearted: !this.state.hearted });
    }
    render() {
        const text = this.state.hearted ? `heart` : `haven't hearted`;
        return (
            <p onClick={this.handleClick.bind(this)}>
                You {text} this. Click to toggle.
            </p>
        );
    }
}

<HeartButton> pure component with props

const HeartButton = ({ hearted, onClick }) => {
    const text = hearted ? `heart` : `haven\'t hearted`;
    return <p onClick={onClick}> You {text} this. Click to toggle. </p>;
}

const ClickCountMessage = ({ clickCount }) => <p> Heart button clicked {clickCount} times </p>
class HeartedController extends React.Component {     constructor(props) {         super(props); this.state = { hearted: false, clickCount: 0 };     }     handleHeartButtonClicked(event) {         this.setState({ hearted: !this.state.hearted, clickCount: this.state.clickCount + 1 });     }     render() {         return (<div>                     <ClickCountMessage clickCount={this.state.clickCount} />                     <HeartButton hearted={this.state.hearted}                                  onClick={this.handleHeartButtonClicked.bind(this)} />                 </div>);     } }

Controlling & Presentation Components


Application architecture


Presentation components (pure stateless functions)

Container component (manage data flow {props} between components)

... or several container components ...


But how do we manage data flow in such a way that's easy to reason about?

MV* ?



Good candidate for CRUD applications

MVC out of control



Good candidate for severe headaches

Flux Application Architecture



Principal concept: Unidirectional data flow

Is a pattern, not a formal framework

Flux Concepts


Store(s) hold application state

Views read from the store but cannot modify a store

The only way to update a store is by sending an Action

Actions can be sent from the View or from data source (e.g. Websocket)

Stores register callbacks with the Dispatcher to receive Actions

Stores emit a change event after updating themselves

Flux Implementations


Implementing your own basic Flux is an excellent learning exercise

In the world of Flux implementations, there is an incredible amount of churn  

Alt.js and Redux are currently in vogue

Redux


Predictable state container for JavaScript apps

Inspired by Flux, but not a pure Flux implementation


Three Fundamental Principles

Single source of truth

The state of your whole application is stored in an object tree within a single store


State is readonly

The only way to mutate state is to emit an action, an object describing what happened


Mutations are written as pure functions

To specify how the state tree is transformed by actions, you write pure reducers

Redux: The Store


{
    visibilityFilter: 'SHOW_ALL',
    todos: [
        {
            text: 'Consider using Redux',
            completed: true
        },
        {
            text: 'Keep all state in a single tree',
            completed: false
        }
    ]
}

Redux: Dispatching actions


const completeTodo(text) => {
    return { type: 'ADD_TODO', text };
}

const setVisibilityFilter(filter) => {     return { type: 'SET_VISIBILITY_FILTER', filter }; }
store.dispatch(completeTodo(1));
store.dispatch(setVisibilityFilter('SHOW_COMPLETED'));

Verbose? Yes!

But also very lucid: the list of action creators is the API surface of your application

Redux: Mutating state


(state, action) => state

function reducer(state = [], action) {
    switch (action.type) {
        case 'ADD_TODO':
            return [
                ...state,
                {
                    text: action.text,
                    completed: false
                }
            ];
        default:
            return state
    }
}

So what does this give you?


Data flow which is predictable and understandable

(therefore quick on-boarding)


The ability to track exactly how your application state changes

(serialisable action + serialisable state)


Superb developer experience

(developers tools which leverage serialised states/actions to provide time travel debugging)

Flux & Redux are independent from React


There are Redux bridges for ng1 and ng2

Also Flux-like and Redux-like implementations .NET and Java

FIN


(almost)

Advertisement


Lambda IT is hiring


We're looking for an enthusiastic, self-reliant developer who's comfortable working with JavaScript

lambda-it.ch