React From Scratch - Software Design & Development...

Post on 20-May-2020

1 views 0 download

Transcript of React From Scratch - Software Design & Development...

@housecor | bitnative.com

Cory House

React From Scratch

github.com/coryhouse/fluent2016Go here and get setup!

Finished demo: github.com/coryhouse/fluent2016complete

Plan to code along with me?

Focus: Code or concepts?

Atom or Webstorm?

Light or dark theme?

Breaks?

Questions:

To code along with me:

git clone https://github.com/coryhouse/fluent2016.git

Start github.com/coryhouse/fluent2016

Finish github.com/coryhouse/fluent2016complete

Code snippets bit.ly/fluent2016reactplan

A World of Components

They call it React for a reason.

JSX

Virtual DOM

Isomorphic Rendering

Unidirectional Flows

Innovation

Try to keep an open mind.

HTML should be a projection of app state, not a source of truth.

JavaScript and HTML belong in the same file.

Unidirectional flow. No two-way binding.

Inline styles can be good.

All Variables Should be Global.

Battle Proven

Morning:

React

Afternoon:

React exercises

Development environment

Testing

Redux

Here’s the Plan

Environment Setup

Everyone done this?

github.com/coryhouse/fluent2016

You don’t need all this tech to work with

React and Flux.

Don’t Let This Scare You…

Just type “npm start”, get all this…

▪ Compile React JSX

▪ Lint JSX and JS via ESLint

▪ Bundle JS and CSS files

▪ Migrate the built app to the dist folder

▪ Run a dev webserver

▪ Open the browser at your dev URL

▪ Reload the browser upon save

Our Goal

Core Technologies

Server-side JavaScript Components

Unidirectional data

flows

Task runner

Node packages in the browser

Routing

Server-side JS

Uses the V8 Engine

Includes npm package manager

Node

.NET

Ruby

Java

Python

PHP

The Web

Node

npm: Node’s Package Manager

CommonJS Pattern

//1. Get reference to dependencyvar dependency = require('/path/to/file');

//2. Declare modulevar MyModule = {//code here…

}

//3. Expose to othersmodule.exports = MyModule;

Use Node modules in the browser

Bundle dependencies

Webpack

Component Library

Simple composition

Utilizes virtual DOM

Can render on client and server

React

Uni-directional data flows

Redux

Run tasks

Rich plugin ecosystem

Stream-based

npm Scripts

Approved June 2015

Widespread browser support

Can transpile to ES5 via Babel

ES2015 (ES6)

Approved in 2009

The JS you already know

Excellent browser support

ES5

What about ES2015?

What about ES2015?

Node & npm Packages

React Components

Redux Data flows

Webpack Bundler

Npm Scripts Automationandbuilds

Wrap Up

JSX

This baby is clearly

adorable.

Imagine an ugly baby here.

“HTML” in JavaScript

Compiles to JavaScript

Differences: className, htmlFor

Optional

JSX

React.createElement("h1", {color: "red"}, "Heading here")

<h1 color="red">Heading here</h1>

JSX Compiles to JS

What about separation of concerns?

“JS” in HTML

<div ng-repeat="user in users">

{{#each user in users}}

data-bind="foreach: users">

“HTML” in JS

{users.map(createUserRow)}

Must stay in sync.

No explicit interface!

Separating intertwined concerns hinders debugging

Compile-time error checking FTW!

M V C

M V C

JSX Friendly Editors

Virtual DOM

Updating the DOM is expensive

Why Virtual DOM?

Compare DOM’s current state to

desired new state.

Update the DOM in the most

efficient way.

With Virtual DOM

Blindly update DOM using new

state.

Without Virtual DOM

The Virtual DOM

Removing a Row…

Redraws entire table Removes the row

Hard to argue with the results…

Performance

Performance

shouldComponentUpdate

PureRenderMixin + immutability

Performance: Go Even Faster

Meh, my app is fast enough.

Half second delay -> 20% drop in traffic.

Delayed in increments of 100

milliseconds

Even very small delays resulted in

substantial drops in revenue.

Synthetic Events

Isomorphic Support

React Native

Hot Reloading

Virtual DOM: More Than Performance

Let’s code our first components!

Time to start coding!

▪ Create our first React components

▪ Setup custom routing

▪ Create centralized layout

▪ Discuss naming conventions

Here’s the Plan

chatApp.jsChatApp.jsxChatApp.react.js

Naming React Files

.js .jsx

All IDEs will at least highlight JS

Default application/icon

Require statements assume JS

Doesn’t distinguish JSX from JS

Lies about contents

May confuse IDE highlighting

Some IDEs won’t highlight any syntax

No default application/icon

Must use .jsx extension to require

Distinguishes JS from JSX

Clarifies content

IDE knows to parse & color as JSX

Which Extension?

React Component Approaches

▪ React component creation approaches

▪ Container vs Presentational Components

Here’s the Plan

Four+ Ways to Create React Components?!

▪ ES5 createClass

▪ ES6 class

▪ ES5 stateless function

▪ ES6 stateless function

▪ Many more…

Ways to Create Components

var HelloWorld = React.createClass({

render: function () {

return (

<h1>Hello World</h1>

);

}

});

ES5 Class Component

class HelloWorld extends React.Component {

constructor(props) {

super(props);

}

render() {

return (

<h1>Hello World</h1>

);

}

}

ES6 Class Component

This slide is with

animations

▪ No autobind

▪ PropTypes declared separately

▪ Default props declared separately

▪ Set initial state in constructor

React in ES6

var HelloWorld = function(props) {

return (

<h1>Hello World</h1>

);

});

ES5 Stateless Functional Component

const HelloWorld = (props) => {

return (

<h1>Hello World</h1>

);

});

ES6 Stateless Functional Component

This slide is with

animations

▪ No class needed

▪ Avoid `this` keyword

▪ Enforced best practices

▪ High signal-to-noise ratio

▪ Enhanced code completion / intellisense

▪ Bloated components are obvious

▪ Easy to understand

▪ Easy to test

▪ Performance

Stateless Functional Components: 9 Benefits

Use stateless functional components when possible.

▪ Class Component

State

Refs

Lifecycle methods

Child functions (for performance)

▪ Stateless Components

Everywhere else ☺

When Should I Use Each?

This slide is with

animations

▪ Object.create

▪ Mixins

▪ Parasitic Components

▪ StampIt

More info: bit.ly/react-define-component

Other Ways to Create Components

Container vs Presentation Components

▪ Container

Little to no markup

Pass data and actions down

Knows about Redux

Often stateful

▪ Presentation

Nearly all markup

Receive data and actions via props

Doesn’t know about Redux

Typically functional components

Most components

Container

Smart

Stateful

Controller View

Presentational

Dumb

Stateless

View

Alternative Jargon

”When you notice that some components

don’t use props they receive but merely

forward them down…it’s a good time to

introduce some container components.”

Dan Abramov

This bullet list is with

animations

▪ ES5 createClass

▪ ES6 Class

▪ ES5 Stateless Function

▪ ES6 Stateless Function

▪ Many more!

▪ Container vs Presentation Components

▪ Next up: Let’s start building!

Wrap up

React Lifecycle

▪ Props

▪ State

▪ Dynamic child components

▪ Lifecycle functions

▪ Demo time!

- Mock API

- Dynamic components

Here’s the Plan

Props – Look like HTML attributes, but immutable

this.props.username

State – Holds mutable state

this.state.username

Props and State

▪ getInitialState

Initial State

▪ getDefaultProps

Default Prop Values

componentWillMount

componentDidMount

componentWillReceiveProps

shouldComponentUpdate

componentWillUpdate

componentDidUpdate

componentWillUnmount

Lifecycle Methods

When

Before initial render, both client and server

Why

Good spot to set initial state

componentWillMount

When

After render

Why

Access DOM, integrate with frameworks, set timers, AJAX requests

componentDidMount

When

When receiving new props. Not called on initial render.

Why

Set state before a render.

componentWillReceiveProps

When

Before render when new props or state are being received.

Not called on initial render.

Why

Performance. Return false to void unnecessary re-renders.

shouldComponentUpdate

When

Immediately before rendering when new props or state are being received.

Not called on initial render.

Why

Prepare for an update

componentWillUpdate

When

After component's updates are flushed to the DOM.

Not called for the initial render.

Why

Work with the DOM after an update

componentDidUpdate

When

Immediately before component is removed from the DOM

Why

Cleanup

componentWillUnmount

Add a key to dynamic child elements

<tr key={author.id}>

Keys for Dynamic Children

Props Pass data to child components

State Data in controller view

Lifecycle Handle bootstrapping and third party integrations

Summary

Composing Components

Our focus: Composition

Controller views

Prop validation via PropTypes

Mixins

Here’s the Plan

Composition

Interacts with storesSets props on

childrenTop level component

Controller Views

Controller Views

propTypes: {

author: React.PropTypes.object.isRequired,

onSave: React.PropTypes.func.isRequired,

validate: React.PropTypes.func.isRequired,

errors: React.PropTypes.object,

hasErrors: React.PropTypes.func.isRequired,

},

Prop Validation

optionalArray: React.PropTypes.array,

optionalBool: React.PropTypes.bool,

optionalFunc: React.PropTypes.func,

optionalNumber: React.PropTypes.number,

optionalObject: React.PropTypes.object,

optionalString: React.PropTypes.string,

Prop Validation

Minified version is for production.

Development vs Production Mode

Declare expected property types

Prop Validation

Controller Views “Smart” components that pass data down via props

PropTypes Validate props

Summary

@housecor bitnative.com

Cory House

Testing and Continuous Integration

This bullet list is with

animations

▪ JavaScript testing styles

▪ 6 key testing decisions

▪ Configure testing and write test

▪ Continuous integration

Here’s the Plan

This slide is with

animations

JavaScript Testing Styles

Style Focus

Unit Single function or module

Integration Interactions between modules

UI Automate interactions with UI

3▪ Helper Libraries

6▪ Where to place tests

1Framework

2▪ Assertion Library

4▪ Where to run tests

5▪ When to run tests

Unit Testing Decisions

Decision #1:Testing Framework

▪ Tape

▪ AVA

Mocha ▪ Jasmine

▪ QUnit ▪ Jest

Testing Frameworks

It’s Like Choosing a Gym

The important part is showing up.

Right Answer Wrong Answer

Any of these!

Woah, decision fatigue!

I’ll just keep coding

and praying.

Decision #2:Assertion Library

This slide is with

animations

▪ Declare what you expect

What’s An Assertion?

expect(2+2).to.equal(4)

assert(2+2).equals(4)

Assertion Libraries

Decision #3:Helper Library

This slide is with

animations

▪ Simulate the browser’s DOM

▪ Run DOM-related tests without a browser

JSDOM

This slide is with

animations

▪ jQuery for the server

▪ Query virtual DOM using jQuery selectors

Cheerio

Decision #4:Where to Run Tests

This slide is with

animations

▪ Browser

- Karma, Testem

▪ Headless Browser

- PhantomJS

▪ In-memory DOM

- JSDOM

Where to Run Tests

Decision #5:Where do test files belong?

Centralized

Less “noise” in src folder

Deployment confusion

Inertia

Alongside

Easy imports

Clear visibility

Convenient to open

No recreating folder structure

Easy file moves

Where Do Test Files Belong?

// file.test.js

import file from '../../src/long/path'

// file.test.js

import file from './file'

Path to file under test is always ./filename ☺

Naming Test Files

Decision #6:When should tests run?

This slide is with

animations

▪ Rapid feedback

▪ Facilitates TDD

▪ Automatic = Low friction

▪ Increases test visibility

Unit Tests Should Run When You Hit Save

But Cory, my tests are

too slow!

- You, my viewer with slow tests

▪ Unit Tests

Test a small unit

Often single function

Fast

Run upon save

▪ Integration Tests

Test multiple units

Often involves clicking and waiting

Slow

Often run on demand, or in QA

3▪ Helper Libraries

6▪ Where to place tests

1Framework

2▪ Assertion Library

4▪ Where to run tests

5▪ When to run tests

Here’s the Plan

ChaiMocha JSDOM

Node Alongside Upon save

Demo

This bullet list is with

animations

▪ Configure automated testing

Continuous Integration

Weird.

Works on my

machine.

- Developer without a CI server

This slide is with

animations

▪ Forgot to commit new file

▪ Forgot to update package.json

▪ Commit doesn’t run cross-platform

▪ Node version conflicts

▪ Bad merge

▪ Didn’t run tests

▪ Catch mistakes quickly

Why CI?

This slide is with

animations

▪ Run Automated build

▪ Run your tests

▪ Check code coverage

▪ Automate deployment

What Does a CI Server Do?

Travis

Continuous Integration

Appveyor Jenkins

Demo

This bullet list is with

animations

▪ Set up Continuous Integration

This bullet list is with

animations▪ Testing frameworks

- Mocha, Jasmine, AVA, Tape, Jest…

▪ Assertion libraries

- Chai, Expect

▪ Helper libraries

- JSDOM, Cheerio

▪ Where to run tests

- Browser, Headless, In memory

▪ Where to place tests, and when to run

▪ Continuous Integration

- Travis CI, Appveyor, Jenkins

▪ Next up: HTTP and Mock APIs

Wrap Up

Demo

This bullet list is with

animations

▪ Production build process

- Lint and runs tests

- Bundle and minify JS and CSS

- Generate JS and CSS sourcemaps

- Exclude dev-specific concerns

- Build React in production mode

- Open prod build in browser

Production Builds Matter

▪ Dev

build▪ 4.8MB

▪ Prod build▪ Essentials

121K 64K!

Drop babel-polyfill, toastr, jQuery, Bootstrap

Flux

A pattern

Centralized dispatcher

Unidrectional data flows

What is Flux?

They call it Flux for a reason too.

Facebook’s Flux

Alt

Reflux

Flummox

Marty

Fluxxor

Delorean

Redux

NuclearJS

Fluxible

Flux Implementations

Good Luck Debugging This

Two-way binding

Two-way Binding vs Unidirectional

React

View

Action

Dispatcher

Store

Unidrectional

View

Viewmodel

Flux: 3 Parts

Delete User

Notify everyone who cares

Hold app state and logic

React

View

Action

Dispatcher

Store

Encapsulate events

Triggered by user interactions and

server

Passed to dispatcher

Actions

React

View

Action

Dispatcher

Store

Actions

React

View

Action

Dispatcher

Store

Payload has type and data

{

type: USER_SAVED

data: {

firstName: ‘Cory’,

lastName: ‘House;

}

}

Central Hub – There’s only one

Holds list of callbacks

Broadcasts payload to registered

callbacks

Sends actions to stores

Dispatcher

React

View

Action

Dispatcher

Store

Keeps things organized

Provides high level view of what the app actually does

Constants

Holds app state, logic, data retrieval

Not a model - Contains models.

One, or many

Registers callbacks with dispatcher

Uses Node’s EventEmitter

Store

React

View

Action

Dispatcher

Store

Every store has these common traits (aka interface)

1. Extend EventEmitter

2. addChangeListener and removeChangeListener

3. emitChange

The Structure of a Store

Dispatcher

Payload

Product

StoreUser Store

Address

Store

{

type: USER_SAVED

data: {

firstName: ‘Cory’,

lastName: ‘House;

}

}

As an application grows, the dispatcher

becomes more vital, as it can be used to

manage dependencies between the stores

by invoking the registered callbacks in a

specific order. Stores can declaratively

wait for other stores to finish updating,

and then update themselves accordingly.Flux Documentation

I usually view ActionCreators as something that is used

for writes to the server. For example, the user added a

new message by clicking the Send button, so the

responsible view calls into ActionCreator.

On the other hand, if a store needs to fetch data from

the server, then that doesn't have to use an

ActionCreator. Instead, the store can directly hit an

endpoint to load its data, and then direct the response

through the dispatcher.Jing Chen, Facebook

Top level component

Interacts with Stores

Holds data in state

Sends data to children as props

Controller Views

React

View

Action

Dispatcher

Store

React View

Action

Dispatcher

Store

Web API

Send

Action

Payload

Send

Action

Payload

Updates storage and

fires change event

Payload sent to dispatcher

Checks for registered callbacks

Sends payload to all registered

callbacks

Receives payload

Store updates and emits change event

Payload:

{

type: USER_SAVED

data: {

firstName: 'Cory',

lastName: 'House';

}

}

User clicked “Save User” button…

Receives change event and re-renders

React Hey CourseAction, someone clicked this “Save Course” button.

Action Thanks React! I registered an action creator with the dispatcher, so the dispatcher should take care of notifying all the stores that care.

Dispatcher Let me see who cares about a course being saved. Ah! Looks like the CourseStore has registered a callback with me, so I’ll let her know.

Store Hi dispatcher! Thanks for the update! I’ll update my data with the payload you sent. Then I’ll emit an event for the React components that care.

React Ooo! Shiny new data from the store! I’ll update the UI to reflect this!

A Chat With Flux

Flux API

register(function callback) – “Hey dispatcher, run me when actions happen. -

Store”

unregister(string id) – “Hey dispatcher, stop worrying about this action. - Store”

waitFor(array<string> ids) – “Update this store first. – Store”

dispatch(object payload) - “Hey dispatcher, tell the stores about this action. -

Action”

isDispatching() – “I’m busy dispatching callbacks right now.”

Flux is a pattern for unidirectional data flows

Actions encapsulate events

Dispatcher is a central hub that holds callbacks

Stores holds app state

Many implementations

Summary

React

View

Action

Dispatcher

Store

Let’s code Flux!

Why Redux?

A Silly Number of Flux Flavors

Flux Many more…Redux

Two Most Popular Flavors

Flux Redux

React

Flux

Redux

Faceboo

k Hires

Redux

Creator

2013

2014

2015

2016

This slide is with

animations

▪ One Store

▪ Reduced Boilerplate

▪ Isomorphic/Universal Friendly

▪ Immutable Store

▪ Hot Reloading

▪ Time-travel debugging

▪ Small

Why Redux?

Boilerplate Magic

Flux Redux

@housecor reactjsconsulting.com

Cory House

Intro to Redux

This bullet list is with

animations

▪ Do I need Redux?

▪ 3 Principles

▪ Flux vs Redux

▪ Redux Flow

Here’s The Plan

Do I need Redux?

Vanilla JS

Simple Complex

jQuery React React + Redux

No setup Significant setup

This slide is with

animations

▪ Complex data flows

▪ Inter-component communication

▪ Non-heirarchical data

▪ Many actions

▪ Same data used in multiple places

When Do I Need Redux?

“…If you aren’t sure if you need it,

you don’t need it.”

Pete Hunt on Flux and Redux

Store

Action: Create User

One immutable store

Redux: 3 Principles

Actions trigger changes Reducers update state

Flux vs Redux

Data down.Actions up.

Unidirectional Flow

Flux and Redux: Similarities

Actions Stores

Reducers

Redux: New Concepts

Containers Immutability

▪ Flux ▪ Redux

Flux vs Redux

React

Action

Dispatcher

Store

React

Action

ReducersStore

▪ Flux

Stores contain state and change logic

▪ Redux

Store and change logic are separate

▪ Flux

Stores contain state and change logic

Multiple stores

▪ Redux

Store and change logic are separate

One store

▪ Flux

Stores contain state and change logic

Multiple stores

Flat and disconnected stores

▪ Redux

Store and change logic are separate

One store

Single store with hierarchical reducers

▪ Flux

Stores contain state and change logic

Multiple stores

Flat and disconnected stores

Singleton dispatcher

▪ Redux

Store and change logic are separate

One store

Single store with hierarchical reducers

No dispatcher

▪ Flux

Stores contain state and change logic

Multiple stores

Flat and disconnected stores

Singleton dispatcher

React components subscribe to stores

▪ Redux

Store and change logic are separate

One store

Single store with hierarchical reducers

No dispatcher

Container components utilize connect

▪ Flux

Stores contain state and change logic

Multiple stores

Flat and disconnected stores

Singleton dispatcher

React components subscribe to stores

State is mutated

▪ Redux

Store and change logic are separate

One store

Single store with hierarchical reducers

No dispatcher

Container components utilize connect

State is immutable

Redux Flow

Redux Flow

function appReducer(state = defaultState, action) {

switch(action.type) {

case RATE_COURSE:

//return new state

}

}

{ type: RATE_COURSE, rating: 5 }

Notified via React-ReduxReact

Action

ReducersStore

This bullet list is with

animations

▪ If you need Redux, you’ll know it.

▪ 3 Principles

- Immutable Store

- Actions trigger changes

- Reducers return updated state

▪ Flux vs Redux

▪ Unidirectional Redux Flow

▪ Next up: Actions, stores, and reducers

Summary

@housecor reactjsconsulting.com

Cory House

Actions, Store, and Reducers

This bullet list is with

animations

▪ Actions

▪ Store

▪ Immutability

▪ Reducers

Here’s The Plan

rateCourse(rating) {

return { type: RATE_COURSE, rating: rating }

}

Action Creators

Action

Action Creator

This slide is with

animations

▪ let store = createStore(reducer);

Creating Redux Store

This slide is with

animations

▪ store.dispatch(action)

▪ store.subscribe(listener)

▪ store.getState()

▪ replaceReducer(nextReducer)

Redux Store

Immutability

Immutability:To change state, return a new object.

▪ Immutable already! ☺

Number

String,

Boolean,

Undefined,

Null

▪ Mutable

Objects

Arrays

Functions

What’s Mutable in JS?

state = {

name: 'Cory House'

role: 'author'

}

state.role = 'admin';

return state;

Current state

Traditional App - Mutating state

state = {

name: 'Cory House'

role: 'author'

}

return state = {

name: 'Cory House'

role: 'admin'

}

Current state

Returning new object. Not mutating state! ☺

Signature

Object.assign(target, ...sources)

Example

Object.assign({}, state, {role: 'admin'});

Copy

▪ Flux

State is mutated

▪ Redux

State is immutable

▪ Clarity

▪ Performance

▪ Awesome Sauce

Why Immutability?

“Huh, who changed that state?”

Immutability = Clarity

The reducer, stupid!

▪ Clarity

▪ Performance

▪ Awesome sauce

Why Immutability?

state = {

name: 'Cory House'

role: 'author'

city: 'Kansas City'

state: 'Kansas'

country: 'USA'

isFunny: 'Rarely'

smellsFunny: ’Often'

...

}

Immutability = Performance

Has this changed?

if (prevStoreState !== storeState) ...

▪ Clarity

▪ Performance

▪ Awesome Sauce

Why Immutability?

(Amazing debugging)

▪ Time-travel debugging

▪ Undo/Redo

▪ Turn off individual actions

▪ Play interactions back

Immutability = AWESOME SAUCE!

Handling Immutability

ES6

▪ Object.assign

▪ Spread operator

ES5

▪ Lodash merge

▪ Lodash extend

▪ Object-assign

Libraries

• react-addons-update

• Immutable.js

Handling Immutable State

JavaScript's primitives are immutable.

Trust

How Do I Enforce Immutability?

redux-immutable-state-

invariant

Immutable.js

Reducers

What is a Reducer?

▪ function myReducer(state, action) {

▪ // Return new state based on action passed

▪ }

This slide is with

animations

(state, action) => state

What is a Reducer?

▪ function myReducer(state, action) {

▪ // Return new state based on action passed

▪ }

So approachable.

So simple.

So tasty.

What is a Reducer?

▪ function myReducer(state, action) {

switch (action.type) {

case ‘INCREMENT_COUNTER’:

state.counter++;

return state;

}

▪ }

Uh oh, can’t do this!

What is a Reducer?

▪ function myReducer(state, action) {

switch (action.type) {

case ‘INCREMENT_COUNTER’:

return (Object.assign(

{},

state,

{counter: state.counter + 1}

);

}

▪ }

Reducers must be pure.

▪ Mutate arguments

▪ Perform side effects

▪ Call non-pure functions

Forbidden in Reducers

1 Store. Multiple Reducers.

New State

authors

loadStatu

s

courses

All Reducers Are Called on Each Dispatch{ type: DELETE_COURSE, 1 }

Reducer = “Slice” of State

authors

courses

loadingStatus

Store

“Write independent small reducer functions

that are each responsible for updates to a

specific slice of state. We call this pattern

“reducer composition”. A given action could

be handled by all, some, or none of them.”Redux FAQ

This bullet list is with

animations

▪ Actions

- Represent user intent

- Must have a type

▪ Store

- dispatch, subscribe, getState…

▪ Immutability

- Just return a new copy

▪ Reducers

- Must be pure

- Multiple per app

- Slice of state

Summary

Next up: Connecting React to Redux

@housecor reactjsconsulting.com

Cory House

Connecting React to Redux

This bullet list is with

animations

▪ Container vs Presentation Components

▪ React-Redux

- Provider

- Connect

▪ A Chat with Redux

Here’s The Plan

▪ Container

Focus on how things work

Aware of Redux

Subscribe to Redux State

Dispatch Redux actions

Generated by react-redux

▪ Presentational

Focus on how things look

Unaware of Redux

Read data from props

Invoke callbacks on props

Written by hand

Two Component Types

Connecting React to Redux

React

Action

ReducersStore

react-redux

Connect

Creates container components▪ Attaches app to store

Provider

React-Redux

<Provider store={this.props.store}>

<App/>

</Provider>

React-Redux Provider

▪ Wraps our component so it’s connected to the Redux store.

Connect

export default connect(

mapStateToProps,

mapDispatchToProps

)(AuthorPage);

onChange() {this.setState({ authors: AuthorStore.getAll() });

}

Flux

componentWillMount() {

AuthorStore.addChangeListener(this.onChange);

}

componentWillUnmount() {

AuthorStore.removeChangeListener(this.onChange);

}

function mapStateToProps(state, ownProps) {

return {appState: state.authorReducer };

}

export default connect(

mapStateToProps,

mapDispatchToProps

)(AuthorPage);

Redux

Benefits:

1. No manual unsubscribe

2. No lifecycle methods required

3. Declare what subset of state you want

4. Enhanced performance for free

connect(mapStateToProps, mapDispatchToProps)

function mapStateToProps(state) {

return {

appState: state

};

}

React-Redux Connect

What state should I expose as props?

▪ Memoize for performance

Reselect

connect(mapStateToProps, mapDispatchToProps)

function mapDispatchToProps(dispatch) {

return {

actions: bindActionCreators(actions, dispatch)

};

}

React-Redux Connect

What actions do I want on props?

this.props.dispatch(loadCourses());

function mapDispatchToProps(dispatch) {

return {

loadCourses: () => {

dispatch(loadCourses());

}

};

}

function mapDispatchToProps(dispatch) {

return {

actions:

bindActionCreators(actions, dispatch)

};

}

Ignore it. Use dispatch.

3 Ways to Handle mapDispatchToProps

Manually wrap

Use bindActionCreators

// In component...

this.props.dispatch(loadCourses())

Two downsides

1. Boilerplate

2. Redux concerns in child components

Option 1: Use Dispatch Directly

function mapDispatchToProps(dispatch) {

return {

loadCourses: () => {

dispatch(loadCourses());

},

createCourse: (course) => {

dispatch(createCourse(course));

},

updateCourse: (course) => {

dispatch(updateCourse(course));

}

};

}

// In component...

this.props.loadCourses()

Option 2: Wrap Manually

function mapDispatchToProps(dispatch) {

return {

actions: bindActionCreators(actions, dispatch)

};

}

// In component:

this.props.actions.loadCourses();

Option 3: bindActionCreators

Wraps action creators in dispatch call for you!

React Hey CourseAction, someone clicked this “Save Course” button.

Action Thanks React! I will dispatch an action so reducers that care can update

state.

Reducer Ah, thanks action. I see you passed me the current state and the action

to perform. I’ll make a new copy of the state and return it.

Store Thanks for updating the state reducer. I’ll make sure that all connected

components are aware.

React-Redux Woah, thanks for the new data Mr. Store. I’ll now intelligently determine

if I should tell React about this change so that it only has to bother with

updating the UI when necessary.

React Ooo! Shiny new data has been passed down via props from the store! I’ll

update the UI to reflect this!

A Chat With Redux

This bullet list is with

animations▪ Container vs Presentation Components

▪ React-Redux

- Provider

- Connect

• mapStateToProps

• mapDispatchToProps

▪ Next up: Let’s code Redux!

Time to code!

@housecor reactjsconsulting.com

Cory House

Async in Redux

This bullet list is with

animations

▪ Why a mock API?

▪ Async libraries

▪ Implement Thunks

Here’s the plan

This slide is with

animations

▪ Start before the API exists

▪ Independence

▪ Backup plan

▪ Ultra-fast

▪ Test slowness

▪ Aids testing

▪ Point to the real API later

Why a Mock API?

▪ Flux

Handed in action

▪ Redux

?

Async

redux-sagaredux-promiseredux-thunk

Redux Async Libraries

▪ Thunks

Functions

Clunky to test

Easy to learn

▪ Sagas

Generators

Easy to test

Hard to learn

Comparison

export function deleteAuthor(authorId) {

return dispatch => {

return AuthorApi.deleteAuthor(authorId).then(() => {

dispatch(deletedAuthor(authorId));

}).catch(handleError);

};

}

Thunk

Demo

This bullet list is with

animations

▪ Let’s get thunky.

This bullet list is with

animations

▪ Thunks, Redux-Promise, and Sagas

▪ Naming async actions

- Consider SUCCESS and ERROR

▪ First thunk, complete!

▪ Next up: Async writes

Wrap Up

Final Thoughts…

The Competition is Responding.

Angular 1 Angular 2 React

Isomorphic x x

Unidirectional x x

1 file per

component

x x

Virtual DOM x x

Hot Reloading x

Browser Support IE8 IE9 IE9

Pluggable x

JSX x

Component Syntax 4 6 10

Yep. But it still won’t be React.

Competition Will Eventually Have All This.

Lightweight, fast, pluggable, isomorphic components in IE8+.

Why React?

Fast

Pluggable

Simple

Testable

Rich Error Messaging

Composable

Broad Browser Support

Isomorphic Friendly

Battle Proven

React Downside

I recently announced my solution…

github.com/coryhouse/react-slingshot

@housecor

There’s much more to be said...

bitnative.com/handouts

Invitation: 5 Minute Retrospective

speakerrate.com@housecor pluralsight.com