The Road To Redux

41
The Road To Redux The React + Redux + Immutable + ES6 Combo

Transcript of The Road To Redux

Page 1: The Road To Redux

The Road To ReduxThe React + Redux + Immutable + ES6 Combo

Page 2: The Road To Redux

Notes From My Crash Course In Redux So Far...By Jeff Sanchez, consultant @ Cielo Concepts

Page 3: The Road To Redux

Why React?

● Fast Rendering Updates (via the much touted “virtual DOM” and associated efficient diff when deciding what to re-render)

● Relatively Easy to Understand (especially in more complex examples)● Large + Growing Enthusiasm / support from tech giant + community● Scales Well (especially with the help of additional libraries)● Easy to Debug (in some sense, there’s not much to go wrong in any given

component)● Flexible - less of a commitment (not really a framework) - use as little or as

much of it as you’d like● Helpful JSX HTML-ish Language

■ (optional, but you’ll probably want it)

Page 4: The Road To Redux

Feel the React Momentum! (from Google Trends)

Page 5: The Road To Redux

JavaScript Frameworks/Libraries With Similar Goals, Or Otherwise Mentioned In The Same Conversation As React

● Angular / MEAN stack● Ember● Backbone● Ext JS / Sencha● Polymer● Meteor / Blaze● Knockout

...And many more lesser known ones. Of the ones I’ve tried, React has been the easiest (at least, for rapid prototyping). Also appears to have more momentum than these do.

Page 6: The Road To Redux

The Oft Done Angular ComparisonAngular

● Two-way data binding● Fairly heavyweight framework● directives, controllers, services● Can be hard to reason about the flow in

some more complex examples● Inject data via scopes● More intuitive looping constructs

(arguably)● Backed heavily by Google● Large established ecosystem

React

● Uni-directional data flow (Flux pattern)● Easy composition / nesting of

components● High performance via virtual DOM● JSX syntax (optional)● Inject data via props● Backed heavily by Facebook● Context switching in JSX land can be

jarring● Smaller ecosystem, though growing fast

Page 7: The Road To Redux

Our 10,000’ View is…

● React, for easy componentization / organization of UI elements● ES6 (ECMAScript 6), for more elegant, easier to read JavaScript code● Redux, for predictable, manageable application state● Node.js for many supporting modules for JavaScript SPAs● Immutable, to help enforce the “Redux Way” (and thus reduce bugs)● Webpack + Babel, for bundling, hot reloading, JavaScript ES6+ language

features, etc.● Pattern Lab, for our ‘living styleguide’ / atomic design approach

Page 8: The Road To Redux

Steps For Developing A React App

From the Facebook React docs, here’s one suggested approach:

1. Initially, start with a mockup of what a particular page should look like2. Break the UI into a component hierarchy3. Build a static version in React (i.e. don’t use state at all yet)4. Identify the minimal, complete version of the state of the UI5. Determine where the state should live, at a component level6. Add inverse data flow as needed (data flowing from components deep in the

hierarchy to ones closer to the top)

Page 9: The Road To Redux

The React Approach, Cont.Create components that can be easily composed into larger components, ultimately making up views.

Components can maintain their own state, and/or can instead have it driven via “props” from parent components

Flexible, less opinionated library + optional expanding ecosystem === use as little or as much of the React world as you’d like.

Unidirectional flow makes debugging / reasoning about app behavior easier - it’s one of the main differentiators between React and Angular.

Page 10: The Road To Redux

Some React Basics

● Component properties are passed from parent component to child, read-only from child’s point of view

● Component can maintain internal state via ‘state’ property● render method outputs React DOM (virtual DOM) elements to be transformed

into actual DOM elements by React● Lifecycle methods provided before/after rendering for components● Easily inline styles with style objects● Components can contained nested components, and reference other

components via refs● JSX syntax makes component rendering easier to follow

Page 11: The Road To Redux

Many Useful Node.js Modules in React ecosystem

Thankfully, there are well tested React/Redux components and associated Node modules (check out npmjs.com, react.rocks, and react-components.com) for:

● Grids (react-datagrid)● Tabs (react-tabs)● Forms (redux-forms)● Modals (react-modal)● Actions (redux-actions)● Logging (redux-logging)● Routing (redux-simple-router)● Asynchronous requests (redux-promise, redux-thunk)● And many more!

Page 12: The Road To Redux

A Bit About React’s JSX language...

JSX is a JavaScript extension that looks similar to XML. It’s optional in React, but is encouraged and used quite a lot. Why? JSX is an easier, more readable syntax for laying out nested component UI.

Typically, you’ll find it in the render method for a React component, when returning what to render. For example:

render () { // JSX - note the JS expression referencing prop values: return <div>Hello {this.props.name}!</div>; }

Page 13: The Road To Redux

ES6 - The JavaScript We’ve Been Looking For

Coming from a Java background myself, some of these changes are quite comforting:

● Class syntax● Module import● Arrow functions (similar to lambda expressions in Java 8)● Destructuring● Rest Spread operator● Improved iterators● Template strings

Page 14: The Road To Redux

ES6 Highlights

Arrow functions are particularly useful, succinct language additions:

E.g.: ES5 “old way” (var and function keywords):

var nums = [1, 2, 3, 4, 5, 6];var squares = nums.map(function (x) { x * x));

Rewritten function with ES6 arrow functions:

let squares = nums(x => x * x);

Page 15: The Road To Redux

ES6 + React Usage

ES6 classes + constructors + module imports work nicely with React:

import React from ‘react’;

export default class Book extends React.Component { constructor(props) { // possibly set up state here, bind functions, etc. }

render () { return (

<div className=”book”><BookSummary id={this.props.id} /><AuthorBio name={this.props.author} />

</div>);

}}

Page 16: The Road To Redux

More ES6 SlicknessDestructuring examples, both for arrays and objects:

let arr = [1, 2, 3, 4];let [first, ,third] = arr; // first === 1, third === 3let person = {firstName: “Mike”, lastName: “Smith”, age: 30};const {firstName, age} = person; // firstName === “Mike”, age === 30

Pretty common to see this pattern at the top of render() methods in React/Redux components:

render () {const {dispatch, someProp, anotherProp} = this.props;

}

Page 17: The Road To Redux

Motivations for Flux (which is…?)

We should address Flux a bit before talking about Redux:

Flux addresses component state management for more complex React applications. Technically, it’s just a pattern of uni-directional data flow development embraced by React. (There are various implementations of Flux.)

Improves code management moving the storage outside of the component.

Page 18: The Road To Redux

More Flux Overview

State is moved to stores, components dispatch actions to the stores via the dispatcher, and their rendering is (mostly) driven by props.

Controller-views (typically, top level components) receive change events emitted by stores and update their state and their children’s state appropriately.

The Flux flow looks like this:

ACTION DISPATCHER STORE

ACTION

VIEW

Page 19: The Road To Redux

Flux Implementations

● Alt (pretty popular - see SurviveJS leanpub book for some good examples)● Flummox (apparently nearing end of life)● Reflux● Facebook’s Flux● Fluxxor● … Some more obscure ones with “Back to the Future”-related names...● Redux (Not exactly Flux, as we’ll see...)

More complete Flux implementation list with some demos: https://github.com/voronianski/flux-comparison

Page 20: The Road To Redux

Redux - Not Exactly Flux

Motivation: How best can we make state mutations predictable in SPAs (Single Page Applications)? Can we support hot reloading / “time travel” debugging / middleware better?

Redux answer: impose restrictions on how / when we can make these state mutations. Their 3 principles:

● Single source of truth ● State is read-only● Pure functions transform state + action into new state

Page 21: The Road To Redux

Redux Benefits

● Hot reloading (don’t lose app state after a code change in a running app instance)

● Time travel debugging (revert to an older application state just by replacing the current state with an older application state snapshot)

● Centralized application state tree (“single source of truth”) - easy to drill down into when debugging. It’s just a big tree data structure (of maps, lists, sets).

● No need to manage multiple stores like in Flux implementations.● Minimal size (2K!) and simple API.

Page 22: The Road To Redux

Redux Concepts

● Actions - created and dispatched to the reducers, which typically produce a new app state

● Reducers - take state + action, and produce the next state● Store - place where entire application state is stored● Data Flow - unidirectional (view -> action -> store -> view)● Thunks for Async actions (cannot have side effects in reducer pure functions)● Immutability (correctness and performance reasons)● Middleware (e.g. logging)● No dispatcher (unlike Flux)

Page 23: The Road To Redux

Immutable and Redux

Problem: how can we prevent inadvertent state mutations, which could cause subtle bugs in the Redux world?

Answer: enforce immutability by using Immutable.js or similar library

Immutable provides data structures such as Sets, Lists, Maps that cannot be mutated. Instead, data structure methods that look like mutators actually return new instances of the data structure they operate on (e.g. set.add(‘something’) returns a new set with ‘something’ added to the original set).

Page 24: The Road To Redux

Immutable Benefits

● Performance boosts in part due to comparison via === (as opposed to deep comparison) when React needs to determine what should be re-rendered.

● Enforces the Redux state immutability concept, thus reducing bugs● Pretty powerful data structure library for manipulating Sets, Lists, Maps, etc.● Well tested / supported● Painlessly convert to/from ordinary JS objects (with toJS()/fromJS())

Page 25: The Road To Redux

Redux Utilities / Related Modules

● redux-logger - easy to use logger middleware● redux-actions - help organize your redux actions● redux-thunk - asynchronous support (e.g. for AJAX requests)● redux-router / redux-simple-router - routing support (map paths to

components)● redux-promise - promise support● redux-devtools - debugging tools (easily navigate current state of redux app

state)● redux-form - nice form support, particularly around validation

Page 26: The Road To Redux

Useful Redux Example Apps

Various Todo App examples are easy to find. (For example, here: http://rackt.org/redux/docs/basics/ExampleTodoList.html)

A very thorough, deep dive into Redux, using a Todo App example, from the creator of Redux (Dan Abramov): https://egghead.io/series/getting-started-with-redux

Another more complex example, involving asynchronous server requests (fetches Reddit headlines): http://rackt.org/redux/docs/advanced/ExampleRedditAPI.html

Page 27: The Road To Redux

Complex Redux Example

Here’s a very good one, with a lot of detail: http://teropa.info/blog/2015/09/10/full-stack-redux-tutorial.html

It’s a live voting app, where items to vote on are paired up tournament-style, and the winners are promoted to the next round against other winners.

Addresses Immutable, unit testing (with mocha + chai), socket.io usage, and a few other cool things.

Has a browser app (with React) and a node server app - they communicate via socket.io.

Page 28: The Road To Redux

Converting Flux to Redux

Here’s one instructive approach - see how it was done for a well documented non-trivial app:

1. Buy and read the React SurviveJS book (https://leanpub.com/survivejs_webpack_react)

2. Work through its React kanban app code (which uses the Alt Flux implementation, not Redux).

3. Then, review the Redux port of that kanban app here: https://github.com/survivejs/redux-demo

Page 29: The Road To Redux

Redux Reducers

A reducer is a function which takes an action + state, and produce a new state. DO NOT mutate existing state! You can use Immutable.js to enforce this. Strongly suggested to do so, to avoid subtle bugs.

const reducer = (state, action) => { switch(action.type) { case ‘ADD_TODO’: return [...state, {text: ‘new todo’ , completed: false}]; default: return state; // by default, reducer should just return the state }}

Page 30: The Road To Redux

Actions / Action CreatorsReact components send out actions which ultimately change the app state via the reducers.

Actions contain some sort of payload, as well as some information regarding their type and whether or not they represent an error of some sort.

Exactly how to organize / structure actions to easily handle error conditions is a major motivating factor for Flux Standard Actions.

Page 31: The Road To Redux

Flux Standard Actions (FSAs)

Motivation: Standard way to handle success / error actions without creating a bunch of constants like ‘SOME_ACTION_SUCCESS’, ‘SOME_ACTION_ERROR’, etc.

Should at least have:

-type

-payload (may be an Error() object with details, if this represents an error)

-optionally some meta info about the action.

Page 32: The Road To Redux

Redux “Smart” vs. “Dumb” Components

● Smart Components (those that know about the Redux store) - the Redux guys suggest keeping these to a minimum, preferably one for the whole application.

● Dumb Components (most of them :) ) - do not know about the Redux store. Completely driven by props from parent component. Dispatches actions in response to user interaction, which are handled by reducers, which ultimately may produce a new app state.

Page 33: The Road To Redux

More Complex Redux Example

Full-featured Grid in Redux (e.g. react-datagrid is a good choice) - but what would we keep in the app store to make this a real Redux component? Potentially the following:

● List of columns to show● Column widths● Which columns are sorted, and in what direction● Selected rows● Filters● Scrollbar positions

Page 34: The Road To Redux

Useful Redux Modules for Node.js

● react-redux (the core Redux library for React)● redux-devtools (development tools to easily inspect the Redux store)● redux-actions (Redux-friendly actions)● redux-logger (Redux logging middleware)● redux-thunk (Async support)● redux-promise (Async support)● react-datagrid (Full-featured tabular data grid)● redux-form (Redux friendly forms)

Page 35: The Road To Redux

Redux Downsides?

● Can be a bit hairy at times to reach into a complex app state tree and find just want you want to change for the next state (get used to Immutable’s API for doing these things)

● Good way to organize actions / reducers is debatable, not so clear? (Here’s one possible way to do it: https://medium.com/lexical-labs-engineering/redux-best-practices-64d59775802e#.f7xvv6f4g)

● As it’s a very different way of doing things, can be hard to get people ‘on board’ with the new paradigm

Page 36: The Road To Redux

Redux Resources

● https://github.com/rackt/react-redux● http://rackt.org/redux/index.html● SurviveJS redone in Redux - nice complex example:● Full tutorial using Redux: http://teropa.info/blog/2015/09/10/full-stack-redux-

tutorial.html● Awesome Redux (quite a long list o’ links): https://github.

com/xgrommx/awesome-redux● https://egghead.io/series/getting-started-with-redux

Page 37: The Road To Redux

Notable React 0.13 + 0.14 Changes

● ES6 style classes now available in 0.13 (so instead of React.createClass(...), you can do class Foo extends React.Component)

● component.getDOMNode is replaced with React.findDOMNode● The DOM part of React is split out into a separate ReactDOM package in 0.14,

so that only the core React code that makes sense for things like React Native are in the React package.

● refs to DOM node components are the DOM nodes themselves (no need to call getDOMNode - 0.14)

● Additional warnings around mutating props

Page 38: The Road To Redux

The Future of React / Redux

Good starting point to look for interesting upcoming changes:

https://github.com/reactjs/react-future

Some highlights:

● Property initializers for state● Property initializers for arrow functions, simplifying binding-related code● props, state passed into render method to eliminate the need for ‘this.’

Page 39: The Road To Redux

Closing Thoughts / Questions

● Will React eventually incorporate some standard version of Redux?● Does Redux have enough momentum in the community to commit to?● Do we even need to bother with Flux anymore?● Is the Redux ecosystem mature enough for production apps?● Are the concepts in Redux easy enough for developers to quickly become

productive?

Page 40: The Road To Redux

A Bit More About Us (Cielo Concepts)...

● Expertise with complex code conversion projects using modern web application technologies (e.g. React / Redux)

● Training available for various popular web development libraries / frameworks (including React / Flux / Redux)

● Design / mockup / usability consulting● Full stack development with Rails, Java, and other established technologies● Pattern Lab training / consultation● Inquire about availability: [email protected]

Page 41: The Road To Redux

Hope This Was Helpful

Will be updating this slide deck often with additional notes from React / Flux/ Redux / ES6 / Immutable land...