Building User Interfaces
with React & Flux

React

Thank You

Burlington JS

John, Matt, Donnie

Who's this guy?

Ben Glassman
Director of Development, Vermont Design Works*
Adjunct Professor, Champlain College
Beer Geek, City of Winooski

Full-stack dev and team lead working on custom web applications.
Part-time zymurgist, full-time dog parent

*Interested in writing apps in React with ES6?
We are hiring front-end and back-end devs!

Things I Like

My Catahoula Leopard Dog Trevor

Not My Favorite Thing

Legacy Code
(a.k.a. The stuff I wrote yesterday)

Overview

Why is UI Programming Hard?
What is React?
Components
Props & State
Event Delegation
JSX
App Example
What is Flux?
Flux App Example
Async with Flux
Async Flux App Example

Why is Programming Interactive UI's Hard?

  • HTML was designed for documents not user interfaces
  • We now use it to build complex user interfaces
  • These interfaces are highly interactive
  • They have lots of state behind them
  • This state changes over time
  • State is spread out throughout the code
  • State can be changed in many places
  • The UI must kept up to date when state changes
  • How do separate UI elements communicate or share state

What exactly is state?

Abstract: The data required to render a given user interface.

Concrete: JSON objects.


const state = {
    comments: [
        {id: 1, text: 'It was great'},
        {id: 2, text: 'It was meh'}
    ],
    loading: false
};

What is React?

A library for creating user interfaces
with composable components.

Used by Facebook, Instagram, Netflix, Yahoo!, Khan Academy, Codecademy.

How does React help?

  • Clear separation of mutable (state) and immutable (props) state
  • Encourages limited mutation of state (props, smart/container vs. dumb components)
  • Makes mutation of state explicit (setState)
  • Encapsulates how state effects rendering into a single place (render)
  • Reduces the need for manual DOM manipulation

Library vs. Framework

React does...

  • Declarative nestable views
    w/ option handling/defaults
    and template rendering
    w/ event delegation
  • Very little else!

React doesnt...

  • HTTP/Network Communication
  • Validation
  • Models/Persistence
  • Routing (react router)
  • Services
  • So much more!

So React is a
Templating Library?
Not really...

Less Like: Rendering HTML (Handlebars, jade, haml).

More Like: Re-usable Components w/ configurable behavior (Angular Directives, jQuery UI Widgets, Web Components)

Example React Component

What will this component render? What behavior will it exhibit?

What is a Component

A component is a small composable unit of a user interface.

A component knows how to output DOM based on state.

Smaller components can be composed together to create more complex user interfaces because they nest like HTML tags.

Kinda Like: Angular directives, jQuery UI Widgets, Web Components

Creating a Component

"If your gonna make a component,
you gotta have a render in the class."

For many components this is all you need.

Rendering your Component

To render a component, we use React.render to
mount our component to a DOM node

Props
Data & Options for Components

  • Javascript Object
  • Accessed via this.props
  • Options or data needed by the component to render
  • Like jQuery plugin options
  • Immutable by convention
  • Defaults & Validation included
  • Syntax like HTML attributes
  • Changes trigger a re-render of component and children
<MyComponent propname="value" >

Props Example:

String Values

JS Values

Validation & Defaults

Event Delegation

  • Syntax looks like inline event handlers but uses delegation under the hood
  • No automatic context/binding (ES6)
<button onClick={this.handleClick.bind(this)}>GO!</button>

Event Example

State
A component's local data

  • Javascript Object
  • Accessed via this.state
  • Initialized in the component's constructor
  • Private to the component
  • Can be mutated by component via this.setState({ key: 'value' })
  • Changes trigger a re-render of component and children

State Example

Props vs. State...
FIGHT!

Props

  • Javascript Object
  • Changes trigger re-render
  • Passed from parent to child
  • Immutable by component
  • Often not serializable (includes callbacks)

State

  • Javascript Object
  • Changes trigger re-render
  • Initialized by component
  • Mutated by the component over time
  • Serializable (simple json object)

Inside the Render Method
The Virtual DOM

  • A component's render method does not return a string
  • The return value is a javascript object the describes the tree of nested components to render.

Render Method Example

render()

render() {
    return <div className="comments"><Comment text="Hello" /></div>
}

Output (simplified)


{
    type: 'div',
    props: {
        className: 'comments',
        children: [
            {
                type: function Comment,
                props: {
                    text: 'Hello'
                    children: []
                }
            }
        ]
    }
}

Virtual DOM

  • This tree structure is called the Virtual DOM.
  • React remembers the virtual dom from component's last render()
  • Whenever props/state changes, recursively call render
  • Compare the new virtual dom to the old for each component
  • Make a batch update at the end of the required DOM changes

Benefits

  • No manual DOM manipulation
  • Minimizes changes to the DOM
  • Easier to reason about what the HTML output will be (Just look at render).
  • Components are guaranteed to update whenever props or state change (no dirty tracking)
  • Support for multiple render targets (DOM, Reactive Native, ??)

JSX
or.. get your filthy HTML out of my Javascript

  • JSX is React's templating language for declaratively describing nested trees of components.
  • Looks just like HTML (except: className, htmlFor)
  • XML-like syntax is highly readable for describing trees

JS vs. JSX

But why put it in the template?

  • Component code is highly cohesive/coupled to rendering code (event delegation, convenience accessors)
  • Reduce context switching between files
  • Component is the logical unit of separation, not technology (HTML vs JS)

Simple Web App Example

JSBin

Flux
An Application Architecture for managing State in React

  • Design Pattern* for managing changing/shared state
  • Advocates for a uni-directional data flow to trigger state changes and propagate state updates to components
  • Defines an application layer where state is stored and changed that lives outside of components

*There are many Flux implementations out there: Alt, Reflux, Fluxible, Redux, McFly, Delorean, Om (ClojureScript) ... seemingly all with pun-y names

Flux Lifecycle in an Oversimplified Nutshell

  1. The user fills out a comment form and clicks the submit button
  2. The form component triggers an AddComment event with data (text, author)
  3. The application layer responsible for handling state changes receives the event and updates its data
  4. ... and emits a change event with the new data
  5. The comment list component can listen for the change event and re-render itself/child components via setState

Using Flux Language

  1. The user fills out a comment form and clicks the submit button
  2. The CommentForm component triggers an AddComment action with data (text, author)
  3. The CommentStore receives the AddComment action and updates its state (adds the comment to a list)
  4. ... and emits a change event with the new state (new comment list)
  5. The CommentList component listening to the CommentStore receives the new state (comment list) and can re-render itself/child components via setState

Try it again with flow charts

Simple Flux App Example

JSBin

Flux Glossary

  • Components: React Components which trigger Actions based on user input (clicks). They pull their data from and listen to changes in Stores.
  • Actions: Events that needs to trigger a state change (e.g. AddComment, DeleteComment, LikeComment) and carry a data payload from Components to the Stores
  • Stores: Where application state lives. Stores are responsible for keeping application state (the list of comments, ids of comments a user likes) updated by listening to Actions and notifying components of changes by emitting change events

What about AJAX/Async?
Depends on the implementation

  1. Async actions which can fail or succeed are generally handled as separate actions: AddComment, AddCommentComplete & AddCommentFailed
  2. The action creator is the name used for a function which a component can call to dispatch an action.
  3. In an action creator for an async action, you would trigger an ajax request and then dispatch the AddCommentComplete or AddCommentFailed actions depending on the result of the request

Example Async Action w/ Completed/Failed


const commentApi = {
  addComment({ newComment }) {
    return new Promise(function(resolve, reject) {
        if (newComment.text && newComment.author) {
          resolve({ newComment: newComment });  
        } else {
          reject({ newComment: newComment, errors: ['Please enter text and an author']});  
        }
    });
  }
};

commentActions.addComment.listen(function(newComment) {
  commentApi.addComment(newComment)
    .then(commentActions.addCommentCompleted)
    .catch(commentActions.addCommentFailed);
});

Async Store Example


const commentStore = {
    data: { errors: [], loading: false, comments: [] },
    init() {
        commentActions.addComment.listen(this.addComment);
        commentActions.addCommentCompleted.listen(this.addComment);
        commentActions.addCommentFailed.listen(this.addComment);
    },
    addComment() {
        this.data.loading = true;
        this.trigger(this.data);
    },
    addCommentCompleted({newComment}) {
        this.data.comments = this.data.comments.concat([newComment]);
        this.data.loading = false;
        this.data.errors = [];
        this.trigger(this.data);
    },
    addCommentCompleted({newComment, errors}) {
        this.data.loading = false;
        this.data.errors = errors;
        this.trigger(this.data);
    }
};

Flux App Example w/ ASYNC/AJAX action

JSBin

BONUS: Local Storage for Persistence

JSBin

BONUS: UNDO/REDO

JSBin

Questions?

Concerns?

Comments?

Criticisms?

Catechisms?
Cannibalisms?
I just wanted to use all six heading levels for once in my life