Slide 1

Slide 1 text

Local State The lesser state to rule the night JavaScriptures IV.II Eve and Chris

Slide 2

Slide 2 text

State

Slide 3

Slide 3 text

React has championed the concept of 1-way data flow

Slide 4

Slide 4 text

Data is passed into a component as props, and components then pass that data to other components as props

Slide 5

Slide 5 text

When data is passed in it is immutable and cannot change

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

If you can't change the data that’s passed into a component, how does one manage state?

Slide 8

Slide 8 text

Via `setState()`

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

setState can only be used in React class components, via `React.Component`

Slide 11

Slide 11 text

No content

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

Can modify state through calls to `setState`, for example on UI interactions

Slide 14

Slide 14 text

No content

Slide 15

Slide 15 text

UI interaction can be easily managed within a single class -- think, button toggles, show / hide, basic http list views

Slide 16

Slide 16 text

No content

Slide 17

Slide 17 text

This works well most of the time!

Slide 18

Slide 18 text

`setState` can take you far, but problems begin to occur when complex UI interactions need to be managed across multiple components

Slide 19

Slide 19 text

No content

Slide 20

Slide 20 text

No content

Slide 21

Slide 21 text

No content

Slide 22

Slide 22 text

When component setState starts to manage App state and is scattered across a codebase it begins to feel suspiciously like MVC and becomes increasingly hard to scale

Slide 23

Slide 23 text

A “predictable state container for JavaScript apps”

Slide 24

Slide 24 text

“ It helps you write applications that behave consistently, run in different environments (client, server, and native), and are easy to test. ” https://redux.js.org/

Slide 25

Slide 25 text

Not a framework, but an architecture for data-flow

Slide 26

Slide 26 text

Not a framework, but an architecture for data-flow ● Based on Flux

Slide 27

Slide 27 text

Not a framework, but an architecture for data-flow ● Based on Flux ● Implements a Unidirectional Data Flow

Slide 28

Slide 28 text

No content

Slide 29

Slide 29 text

Single source of truth “The state of your whole application is stored in an object tree within a single store.” What is Redux?

Slide 30

Slide 30 text

State is read-only The only way to change the state is to emit an action, an object describing what happened. What is Redux?

Slide 31

Slide 31 text

Changes are Made with Pure Functions To specify how the state tree is transformed by actions, you write pure reducers. What is Redux?

Slide 32

Slide 32 text

Basic Redux Concepts

Slide 33

Slide 33 text

Store ● A plain object, this is our one true source ● The provider of a universal state to your entire app

Slide 34

Slide 34 text

Slide 35

Slide 35 text

Store ● A plain object, this is our one true source, ● The provider of a universal state to your entire app Actions ● Centralized set of functions for manipulating data in the store ● All actions return a plain object describing what happened

Slide 36

Slide 36 text

export const changeAdminStatus = ({isAdmin}) => ({ type: actions.CHANGE_ADMIN_STATUS, payload: { isAdmin } }) export const actions = { CHANGE_ADMIN_STATUS: 'CHANGE_ADMIN_STATUS' }

Slide 37

Slide 37 text

export const changeAdminStatus = ({isAdmin}) => ({ type: actions.CHANGE_ADMIN_STATUS, payload: { isAdmin } }) export const fetchUsers = () => { return async (getState) => { const users = await http.get(‘/users’) return { type: actions.FETCH_USERS, payload: { users } } } } export const actions = { CHANGE_ADMIN_STATUS: 'CHANGE_ADMIN_STATUS' FETCH_USERS: 'FETCH_USERS' } With the introduction of middleware...

Slide 38

Slide 38 text

Store ● A plain object, this is our one true source, ● The provider of a universal state to your entire app Actions ● Centralized set of functions for manipulating data in the store ● All actions return a plain object describing what happened Reducers ● Called with two arguments from the store: the current state tree and an action ● Outlines the shape of an initial state

Slide 39

Slide 39 text

export function appReducer (state = initialState, action) { switch (action.type) { case CHANGE_ADMIN_STATUS: return Object.assign({}, state, { isAdmin: action.payload.isAdmin }) default: return state } }

Slide 40

Slide 40 text

No content

Slide 41

Slide 41 text

Dispatch ● The thread between the store/reducer/actions

Slide 42

Slide 42 text

store.dispatch(someAction())

Slide 43

Slide 43 text

Dispatch ● The thread connecting the store/reducer/actions Middleware ● Interrupt dispatched actions with libraries or your own functions

Slide 44

Slide 44 text

Use Case Positron (aka Writer)

Slide 45

Slide 45 text

No content

Slide 46

Slide 46 text

Legacy Setup in Positron

Slide 47

Slide 47 text

● Backbone used for models

Slide 48

Slide 48 text

● Backbone used for models ● React components rendered inside Backbone parent views

Slide 49

Slide 49 text

● Backbone used for models ● React components rendered inside Backbone parent views ● Mixture of Backbone and React in UI components

Slide 50

Slide 50 text

● Backbone used for models ● React components rendered inside Backbone parent views ● Mixture of Backbone and React in UI components ● React components used Backbone’s set/get methods for all data mutations

Slide 51

Slide 51 text

Pitfalls of Legacy Setup

Slide 52

Slide 52 text

React and Backbone elements in same UI could have separate instances of shared data

Slide 53

Slide 53 text

React and Backbone elements in same UI could have separate instances of shared data ● React and Backbone lifecycles exist independently from each other ● Listeners for Backbone ‘change’ events were scattered throughout app to trigger re-renders

Slide 54

Slide 54 text

React and Backbone elements in same UI could have separate instances of shared data ● React and Backbone lifecycles exist independently from each other ● Listeners for Backbone ‘change’ events were scattered throughout app to trigger re-renders Props and onChange functions were passed down the entire component tree

Slide 55

Slide 55 text

React and Backbone elements in same UI could have separate instances of shared data ● React and Backbone lifecycles exist independently from each other ● Listeners for Backbone ‘change’ events were scattered throughout app to trigger re-renders Props and onChange functions were passed down the entire component tree ● Bug fixing is hard when tracking through deep layers of nesting

Slide 56

Slide 56 text

React and Backbone elements in same UI could have separate instances of shared data ● React and Backbone lifecycles exist independently from each other ● Listeners for Backbone ‘change’ events were scattered throughout app to trigger re-renders Props and onChange functions were passed down the entire component tree ● Bug fixing is hard when tracking through deep layers of nesting Data loss and views becoming out-of-sync is possible when components unmount

Slide 57

Slide 57 text

React and Backbone elements in same UI could have separate instances of shared data ● React and Backbone lifecycles exist independently from each other ● Listeners for Backbone ‘change’ events were scattered throughout app to trigger re-renders Props and onChange functions were passed down the entire component tree ● Bug fixing is hard when tracking through deep layers of nesting Data loss and views becoming out-of-sync is possible when components unmount ● Rather than conditionally mounting components, we’d use jQuery to hide them

Slide 58

Slide 58 text

No content

Slide 59

Slide 59 text

Benefits of Moving to Redux

Slide 60

Slide 60 text

One true source: Centralized data store is available to all components ● A consistent source for editable data ● But also can contain other information, like saved status or client errors

Slide 61

Slide 61 text

No content

Slide 62

Slide 62 text

One true source: Centralized data store is available to all components ● A consistent source for editable data ● But also can contain other information, like saved status or client errors Components that access centralized store re-render automatically when data changes ● This operation can be memoized for highly performant update cycles

Slide 63

Slide 63 text

One true source: Centralized data store is available to all components ● A consistent source for editable data ● But also can contain other information, like saved status or client errors Components that access centralized store re-render automatically when data changes ● This operation can be memoized for highly performant update cycles Functions for mutating and saving data are consolidated to a centralized set of actions ● Makes it easy to jump into a new codebase and see what’s possible

Slide 64

Slide 64 text

No content

Slide 65

Slide 65 text

… and there’s more

Slide 66

Slide 66 text

Minimize props that are passed down component tree ● By Connecting components, you can access the app’s store in them directly

Slide 67

Slide 67 text

No content

Slide 68

Slide 68 text

Minimize props that are passed down component tree ● By Connecting components, you can access the app’s store in them directly Ability to log and track all calls to Redux actions in the console

Slide 69

Slide 69 text

No content

Slide 70

Slide 70 text

Should I Be Using This?

Slide 71

Slide 71 text

No content

Slide 72

Slide 72 text

● Managing state with setState has become overly complicated

Slide 73

Slide 73 text

● Managing state with setState has become overly complicated ● State is shared between components that don’t have a parent/child relationship

Slide 74

Slide 74 text

● Managing state with setState has become overly complicated ● State is shared between components that don’t have a parent/child relationship ● State changes are reflected outside the component where they are triggered, or are paired with asynchronous functions

Slide 75

Slide 75 text

● Managing state with setState has become overly complicated ● State is shared between components that don’t have a parent/child relationship ● State changes are reflected outside the component where they are triggered, or are paired with asynchronous functions ● Following how your state changes is opaque, and a step-through/undo history is necessary to understand it

Slide 76

Slide 76 text

● Managing state with setState has become overly complicated ● State is shared between components that don’t have a parent/child relationship ● State changes are reflected outside the component where they are triggered, or are paired with asynchronous functions ● Following how your state changes is opaque, and a step-through/undo history is necessary to understand it ● Props are passed down the component tree liberally, including through places they aren’t used

Slide 77

Slide 77 text

Create predictable, trackable outcomes

Slide 78

Slide 78 text

Debug complex systems with ease

Slide 79

Slide 79 text

Facilitate clean, clear code