Upgrade to Pro — share decks privately, control downloads, hide ads and more …

JavaScriptures 4.2 - Local State

JavaScriptures 4.2 - Local State

Fec952eb14022f55b2747510ac685591?s=128

Artsy Open Source

April 12, 2018
Tweet

Transcript

  1. Local State The lesser state to rule the night JavaScriptures

    IV.II Eve and Chris
  2. State

  3. React has championed the concept of 1-way data flow

  4. Data is passed into a component as props, and components

    then pass that data to other components as props
  5. When data is passed in it is immutable and cannot

    change
  6. None
  7. If you can't change the data that’s passed into a

    component, how does one manage state?
  8. Via `setState()`

  9. None
  10. setState can only be used in React class components, via

    `React.Component`
  11. None
  12. None
  13. Can modify state through calls to `setState`, for example on

    UI interactions
  14. None
  15. UI interaction can be easily managed within a single class

    -- think, button toggles, show / hide, basic http list views
  16. None
  17. This works well most of the time!

  18. `setState` can take you far, but problems begin to occur

    when complex UI interactions need to be managed across multiple components
  19. None
  20. None
  21. None
  22. 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
  23. A “predictable state container for JavaScript apps”

  24. “ 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/
  25. Not a framework, but an architecture for data-flow

  26. Not a framework, but an architecture for data-flow • Based

    on Flux
  27. Not a framework, but an architecture for data-flow • Based

    on Flux • Implements a Unidirectional Data Flow
  28. None
  29. Single source of truth “The state of your whole application

    is stored in an object tree within a single store.” What is Redux?
  30. State is read-only The only way to change the state

    is to emit an action, an object describing what happened. What is Redux?
  31. Changes are Made with Pure Functions To specify how the

    state tree is transformed by actions, you write pure reducers. What is Redux?
  32. Basic Redux Concepts

  33. Store • A plain object, this is our one true

    source • The provider of a universal state to your entire app
  34. <Provider store={store}> <App /> </Provider>

  35. 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
  36. export const changeAdminStatus = ({isAdmin}) => ({ type: actions.CHANGE_ADMIN_STATUS, payload:

    { isAdmin } }) export const actions = { CHANGE_ADMIN_STATUS: 'CHANGE_ADMIN_STATUS' }
  37. 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...
  38. 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
  39. export function appReducer (state = initialState, action) { switch (action.type)

    { case CHANGE_ADMIN_STATUS: return Object.assign({}, state, { isAdmin: action.payload.isAdmin }) default: return state } }
  40. None
  41. Dispatch • The thread between the store/reducer/actions

  42. store.dispatch(someAction())

  43. Dispatch • The thread connecting the store/reducer/actions Middleware • Interrupt

    dispatched actions with libraries or your own functions
  44. Use Case Positron (aka Writer)

  45. None
  46. Legacy Setup in Positron

  47. • Backbone used for models

  48. • Backbone used for models • React components rendered inside

    Backbone parent views
  49. • Backbone used for models • React components rendered inside

    Backbone parent views • Mixture of Backbone and React in UI components
  50. • 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
  51. Pitfalls of Legacy Setup

  52. React and Backbone elements in same UI could have separate

    instances of shared data
  53. 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
  54. 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
  55. 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
  56. 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
  57. 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
  58. None
  59. Benefits of Moving to Redux

  60. 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
  61. None
  62. 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
  63. 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
  64. None
  65. … and there’s more

  66. Minimize props that are passed down component tree • By

    Connecting components, you can access the app’s store in them directly
  67. None
  68. 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
  69. None
  70. Should I Be Using This?

  71. None
  72. • Managing state with setState has become overly complicated

  73. • Managing state with setState has become overly complicated •

    State is shared between components that don’t have a parent/child relationship
  74. • 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
  75. • 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
  76. • 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
  77. Create predictable, trackable outcomes

  78. Debug complex systems with ease

  79. Facilitate clean, clear code