react state management with redux and mobx

93
React State Management with Redux and MobX DARKO KUKOVEC @DarkoKukovec ANDREI ZVONIMIR CRNKOVI Ć @andreicek INFINUM @infinumco

Upload: darko-kukovec

Post on 29-Jan-2018

841 views

Category:

Technology


3 download

TRANSCRIPT

Page 1: React state management with Redux and MobX

React State Management with Redux and MobX

DARKO KUKOVEC @DarkoKukovec ANDREI ZVONIMIR CRNKOVIĆ @andreicek

INFINUM @infinumco

Page 2: React state management with Redux and MobX

DARKO KUKOVEC JS Team Lead

@DarkoKukovec

ANDREI ZVONIMIR CRNKOVIĆ JS Emojineer @andreicek

Page 3: React state management with Redux and MobX

We're an independent design & development agency.

Page 4: React state management with Redux and MobX

Topic

Time

SCHEDULE

13:45-14:30 14:30-15:15 15:15-16:00

React setState React + Redux React + MobX

The Joy of Optimizing

Una Kravets (DigitalOcean)

Coffee.js? How I hacked my coffee machine using

JavaScript

Dominik Kundel (Twilio)

GraphQL: Data in modern times

Dotan Simha (The Guild)

Page 5: React state management with Redux and MobX

01APP STATE

Page 6: React state management with Redux and MobX

APP STATE

• Data • Which user is logged in? • Which todos did the user create?

• UI • Which todos is the user looking at (filter - all, complete, incomplete)

Page 7: React state management with Redux and MobX

02STATE MANAGEMENT

Page 8: React state management with Redux and MobX

STATE MANAGEMENT

• What should happen when some data changes?

• Does the UI need to be updated

• Does some other data depend on it?

• Does the app need to make an action (e.g. API call)?

Page 9: React state management with Redux and MobX

03WHY DO WE NEED IT?

Page 10: React state management with Redux and MobX

IMAGE GOES INSIDE THIS BOX DELETE BOX AFTER PLACING IMAGE

Page 11: React state management with Redux and MobX

• Todos

• Title

• Status

• Active filter

• Number of todos

Page 12: React state management with Redux and MobX

Handing an action in the app

Page 13: React state management with Redux and MobX

Handing an action in the app

• The user checks a todo as complete

Page 14: React state management with Redux and MobX

Handing an action in the app

• The user checks a todo as complete

• Mark the todo as complete

Page 15: React state management with Redux and MobX

Handing an action in the app

• The user checks a todo as complete

• Mark the todo as complete

• Update the incomplete items count

Page 16: React state management with Redux and MobX

Handing an action in the app

• The user checks a todo as complete

• Mark the todo as complete

• Update the incomplete items count

• What filter is active again?

Page 17: React state management with Redux and MobX

Handing an action in the app

• The user checks a todo as complete

• Mark the todo as complete

• Update the incomplete items count

• What filter is active again?

• Do I need to update the list of todos?

• Add/remove item?

• Sort items?

• Should I show an empty state?

• Should I make an API call?

• Should I save the change into

localStorage?

Page 18: React state management with Redux and MobX

Data Flow in JavaScript Applications - Ryan Christiani

Page 19: React state management with Redux and MobX

04EXAMPLE PROJECT

Page 20: React state management with Redux and MobX

EXAMPLE PROJECT

• Tech conference app

• Fetch talk list (async action)

• Favourite talks (simple sync action)

• Filter by location (filtering data from the state)

• To simplify • No routing • No forms • Not responsive • Only basic styling • Assumption: Browsers support Fetch API

• 70% of browsers do, polyfill available for the rest

Page 21: React state management with Redux and MobX

EXAMPLE PROJECT - TECH STUFF

• create-react-app as the initial setup

• https://github.com/infinum/shift-2017

Page 22: React state management with Redux and MobX

05BEFORE WE START...

Page 23: React state management with Redux and MobX

COMPONENT TYPES

Container Presenter

Usually root components Inside of container components

No UI Only UI

State of children components Dumb component

Handle state changes "Data down, actions up"

Page 24: React state management with Redux and MobX

06PREREQUISITES

Page 25: React state management with Redux and MobX

PREREQUISITES

• A modern IDE (VS Code, Sublime Text, Atom, Webstorm or similar)

• Latest version of Chrome/Chromium for debugging

• Node.js 6 or 7

• npm 4 or yarn

Page 26: React state management with Redux and MobX

07REACT + SETSTATE

Page 27: React state management with Redux and MobX

REACT + SETSTATE

• No central state

• Every component contains its (and children?) state

• State changes are async! - 2nd argument is a callback

• Component is re-rendered unless shouldComponentUpdate() returns false

• Additional libs • react-addons-update

Page 28: React state management with Redux and MobX

// Code time! // setState // Code used for setup: create-react-app app-setstate npm install --save react-addons-update

v1.0

Page 29: React state management with Redux and MobX

* Mock data * Styles * Presenter components * Utils

v1.0

Page 30: React state management with Redux and MobX

// Loading data

v1.0

Page 31: React state management with Redux and MobX

// Container component state

v1.1

Page 32: React state management with Redux and MobX

// Selectors

v1.2

Page 33: React state management with Redux and MobX

FUNCTIONAL SETSTATE

• Since React 15?

• Will eventually replace the usage with objects as the first argument

Page 34: React state management with Redux and MobX

class App extends Component { constructor(props) { super(props); this.state = {counter: 0}; }

increaseCounter() { this.setState({ counter: this.state.counter + 1 }); }

decreaseCounter() { this.setState((prevState, props) => { return {counter: prevState.counter + 1}; }); }

render() { // ... } }

Page 35: React state management with Redux and MobX

SCALING SETSTATE

• A bad idea • One master component with app state • Some smaller independent containers

Page 36: React state management with Redux and MobX

08MOBX VS REDUX

Page 37: React state management with Redux and MobX

http:!//!!www.timqian.com/star-history/#mobxjs/mobx&reactjs/redux&facebook/flux&facebook/relay

Page 38: React state management with Redux and MobX

ADVANTAGES

Easier to (unit) test

MobX Redux

Faster

Less boilerplate Smaller

Time travelMore flexible

Easier to debug?Simpler async actions

Page 39: React state management with Redux and MobX

IN THE NUTSHELL...

https:!//twitter.com/phillip_webb/status/705909774001377280

Page 40: React state management with Redux and MobX

USAGE

MobX Redux

mobx-react react-redux

Not React dependent Not React dependent

mobx-angular

Python

GWT

Page 41: React state management with Redux and MobX

09REACT + REDUX

Page 42: React state management with Redux and MobX

REACT + REDUX

• One central state

• Additional libs • redux • react-redux • redux-thunk

Page 43: React state management with Redux and MobX

STORE Holds application state

Page 44: React state management with Redux and MobX

ACTIONS Payloads of information that send data from your

application to your store

Page 45: React state management with Redux and MobX

REDUCERS Specify how the application's state changes in

response to actions

Page 46: React state management with Redux and MobX

import { createStore } from 'redux'

function counter(state = 0, action) { switch (action.type) { case 'INCREMENT': return state + 1 case 'DECREMENT': return state - 1 default: return state } }

let store = createStore(counter)

store.subscribe(() => console.log(store.getState()) )

store.dispatch({ type: 'INCREMENT' }) // 1 store.dispatch({ type: 'INCREMENT' }) // 2 store.dispatch({ type: 'DECREMENT' }) // 1

THE GIST

Page 47: React state management with Redux and MobX

// Code time! // Redux // Code used for setup: create-react-app app-redux npm install --save redux react-redux redux-thunk

v2.0

Page 48: React state management with Redux and MobX

* Mock data * Styles * Presenter components * Utils

v2.0

Page 49: React state management with Redux and MobX

// Action names

v2.0

Page 51: React state management with Redux and MobX

// Reducers

v2.2

Page 54: React state management with Redux and MobX

// Selectors

v2.5

Page 55: React state management with Redux and MobX

// Redux DevTools // https://chrome.google.com/webstore

https:!//chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd?hl=env2.6

Page 56: React state management with Redux and MobX

SCALING REDUX

• Only one store!

• Multiple (nested) reducers, actions • Store data nesting === reducer nesting

• "reducers" folder, "actions" folder

• Folders based on functionality • e.g. "orders" contains a orders reducer, orders actions and all other related stuff

Page 57: React state management with Redux and MobX

THINGS TO KEEP IN MIND

• NEVER mutate the state!

• Immutable.js

Page 58: React state management with Redux and MobX

09REDUX HELPER LIBS

Page 59: React state management with Redux and MobX

IMMUTABLE.JS

• https://github.com/facebook/immutable-js/

• List, Stack, Map, OrderedMap, Set, OrderedSet, Record

• Nested structures

Page 60: React state management with Redux and MobX

REDUX FORM

• https://github.com/erikras/redux-form

• Uses Immutable.js

• Sync/async validations

• Wizard forms

Page 61: React state management with Redux and MobX

REDUX - THE SOURCE CODE

https:!//twitter.com/bloodyowl/status/740228059538857984

Page 62: React state management with Redux and MobX

10REACT + MOBX

Page 63: React state management with Redux and MobX

REACT + MOBX

• One/multiple states

• Additional libs • mobx • mobx-react

Page 64: React state management with Redux and MobX

Anything that can be derived from the application state, should be derived. Automatically.

- The philosophy behind MobX

Page 65: React state management with Redux and MobX

OBSERVABLE Your state

e.g., list of TODOs

Page 66: React state management with Redux and MobX

ACTION A function that changes the state

e.g., function called after the user clicks on the completed checkbox

Page 67: React state management with Redux and MobX

COMPUTED PROPERTY A value derived from your state e.g., list of completed TODOs

Page 68: React state management with Redux and MobX

OBSERVER Function (component?) that needs to be updated

on state change e.g., component showing a list of TODOs

Page 69: React state management with Redux and MobX

STATE (OBSERVABLES)

COMPUTED PROPS

OBSERVERSACTION

UPDATES

UPDATESUPDATESCHANGES

Page 70: React state management with Redux and MobX

THE GIST

import { observable, autorun } from 'mobx';

const store = observable({counter: 0});

autorun(() => console.log(store.counter); );

store.counter++; // 1 store.counter++; // 2 store.counter--; // 1

Page 71: React state management with Redux and MobX

import { createStore } from 'redux'

function counter(state = 0, action) { switch (action.type) { case 'INCREMENT': return state + 1 case 'DECREMENT': return state - 1 default: return state } }

let store = createStore(counter)

store.subscribe(() => console.log(store.getState()) )

store.dispatch({ type: 'INCREMENT' }) // 1 store.dispatch({ type: 'INCREMENT' }) // 2 store.dispatch({ type: 'DECREMENT' }) // 1

THE GIST

import { observable, autorun } from 'mobx';

const store = observable({counter: 0});

autorun(() => console.log(store.counter); );

store.counter++; // 1 store.counter++; // 2 store.counter--; // 1

MobX Redux

Page 72: React state management with Redux and MobX

DECORATORS JS proposed feature (Babel plugin)

TypeScript feature

Page 73: React state management with Redux and MobX

import {observable, computed} from 'mobx';

class Todos { @observable list = []; users = observable([]);

@computed get complete() { return this.list.filter((todo) => todo.complete); }

incomplete: computed(() => { return this.list.filter((todo) => !todo.complete); }) }

Page 74: React state management with Redux and MobX

// Code time! // MobX // Code used for setup: create-react-app app-mobx --scripts-version custom-react-scripts

npm install --save mobx mobx-react

v3.0

Page 75: React state management with Redux and MobX

* Mock data * Styles * Presenter components * Utils

v3.0

Page 77: React state management with Redux and MobX

// Loading data

v3.1

Page 78: React state management with Redux and MobX

// Actions

v3.2

Page 79: React state management with Redux and MobX

// Observers

v3.3

Page 80: React state management with Redux and MobX

// Strict mode

v3.4

Page 81: React state management with Redux and MobX

THINGS TO KEEP IN MIND

• use extendObservable to add properties to an object

• Wrapped objects - isArray(arr) or array.is(toJS(arr)) • Don't be afraid to use observers

• If done right: More observers → better performance

Page 82: React state management with Redux and MobX

SCALING MOBX

• Your code can be object oriented!

• A list of best practices

• Strict mode, actions (transactions)

• Use helper libs

Page 83: React state management with Redux and MobX

10MOBX HELPER LIBS

Page 84: React state management with Redux and MobX

MOBX-REACT-DEVTOOLS

• Log actions & reactions

• Check dependencies for a react component

• Show update times

Page 85: React state management with Redux and MobX
Page 86: React state management with Redux and MobX

"STRUCTURE" LIBS Opinionated

Page 87: React state management with Redux and MobX

MOBX-COLLECTION-STORE

• https://github.com/infinum/mobx-collection-store

• One collection, multiple model types

• Relationships between models

• mobx-jsonapi-store

• https://github.com/infinum/mobx-jsonapi-store

Page 88: React state management with Redux and MobX

MOBX-STATE-TREE

• https://github.com/mobxjs/mobx-state-tree

• Made by MobX authors

• v1.0 release soon

• Supports snapshots, replay, JSON patches, etc.

• Supports time travel! • Compatible with Redux DevTools!

Page 89: React state management with Redux and MobX

MOBX-REACT-FORM

• https://github.com/foxhound87/mobx-react-form

• Dedicated DevTools: https://github.com/foxhound87/mobx-react-form-devtools

Page 90: React state management with Redux and MobX

REACT SETSTATE + MOBX

• You can still use it

• But, you can also do this…

Page 91: React state management with Redux and MobX

import {observable} from 'mobx'; import {observer} from 'mobx-react'; import React, {Component} from 'react';

@observer export default class Foo extends Component { @observable state = { clickCount = 0; };

onClick: () => { this.state.clickCount++; // if you use setState it will stop being an observable! }

render() { return ( <button onClick={this.onClick}> { this.state.clickCount ? `Clicked ${this.state.clickCount} times!` : 'Click me!' } </button> ); } }

Page 92: React state management with Redux and MobX

RESOURCES

• Redux • http://redux.js.org/ • https://egghead.io/courses/getting-started-with-redux • https://egghead.io/courses/building-react-applications-with-idiomatic-redux

• MobX • https://mobx.js.org/ • https://mobxjs.github.io/mobx/getting-started.html • https://egghead.io/courses/manage-complex-state-in-react-apps-with-mobx

Page 93: React state management with Redux and MobX

Visit infinum.co or find us on social networks:

infinum.co infinumco infinumco infinum

Thank you! [email protected] @DARKOKUKOVEC

[email protected] @ANDREICEK