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

setState Machine

setState Machine

What if your components' state was deterministic?
Learn about the implementation of State Machines to manage React Components' state - from the basics of Automata theory to autogenerated tests.

Michele Bertoli

April 13, 2018
Tweet

More Decks by Michele Bertoli

Other Decks in Programming

Transcript

  1. setState Machine
    @MicheleBertoli

    View Slide

  2. I’m Michele, a React fanboy

    View Slide

  3. I work in Ads at Facebook and I
    build user interfaces

    View Slide

  4. State is hard

    View Slide

  5. Infinite Scroll
    ● Attach an event handler to scroll
    ● Check if the user scrolled > 90%
    ● Fetch more data

    View Slide

  6. if (scrollPercentage > 0.9) {
    this.fetch()
    }

    View Slide

  7. if (
    scrollPercentage > 0.9 &&
    !this.state.isFetching
    ) {
    this.fetch()
    }

    View Slide

  8. {this.state.isFetching
    ? 'Loading...'
    : null}

    View Slide

  9. if (!data.hasMore) {
    this.detach()
    }

    View Slide

  10. {this.state.hasError
    ? 'Something went wrong'
    : null}

    View Slide

  11. {isEmpty
    ? (isFetching ? Loading... : Empty.)
    :


    }
    source: github.com/reactjs/redux

    View Slide

  12. Bottom-up
    ● Focus on linear transitions
    ● Hard to understand
    ● Edge cases

    View Slide

  13. State Machine

    View Slide

  14. Automata Theory
    ● Abstract machines
    ● Deterministic finite automata

    View Slide

  15. A B C
    α β

    View Slide

  16. SEMI NO-SEMI
    TOGGLE
    TOGGLE

    View Slide

  17. SEMI
    SPACE
    SEMI
    TAB
    NO-SEMI
    TAB
    NO-SEMI
    SPACE
    TOGGLE SEMI
    TOGGLE SEMI
    USE TAB USE TAB

    View Slide

  18. Statecharts

    View Slide

  19. “A visual formalism
    for complex systems.”
    David Harel, 1987

    View Slide

  20. Statecharts
    Extension of the conventional
    formalism of state machines and
    state diagrams

    View Slide

  21. Clustering

    View Slide

  22. C
    A
    B
    β
    β
    α

    View Slide

  23. β
    C
    A
    B
    α

    View Slide

  24. β
    C
    D

    View Slide

  25. Orthogonality

    View Slide

  26. A
    B
    C
    D

    View Slide

  27. Guards

    View Slide

  28. A
    B
    event [guard]

    View Slide

  29. Actions

    View Slide

  30. A
    B
    event / action

    View Slide

  31. A
    entry action1
    exit action2, action3

    View Slide

  32. Workflow

    View Slide

  33. Statechart
    Event Actions

    View Slide

  34. “A statechart is a magic-box:
    you tell it what happened,
    and it tells you what to do.”
    Luca Matteis, 2018

    View Slide

  35. yarn add xstate

    View Slide

  36. xstate
    Functional, Stateless JS Finite State
    Machines and Statecharts

    View Slide

  37. entry removeSemicolons
    entry addSemicolons
    noSemi
    semi
    TOGGLE
    TOGGLE

    View Slide

  38. const prettyMachine = Machine({
    initial: 'semi',
    states: {
    semi,
    noSemi,
    },
    })

    View Slide

  39. const semi = {
    on: { TOGGLE: 'noSemi' },
    onEntry: 'addSemicolons',
    }

    View Slide

  40. const noSemi = {
    on: { TOGGLE: 'semi' },
    onEntry: 'removeSemicolons',
    }

    View Slide

  41. const { actions } = prettyMachine
    .transition('semi', 'TOGGLE')
    // => ["removeSemicolons"]

    View Slide

  42. yarn add react-automata

    View Slide

  43. react-automata
    A state machine abstraction for
    React

    View Slide

  44. start
    entry attach
    listening
    SUCCESS [hasMore]
    ERROR / error
    SCROLL [scrollPercentage > 0.9]
    READY
    fetching
    entry fetch
    finish
    SUCCESS [!hasMore]
    entry detach

    View Slide

  45. withStatechart(statechart)(MyInfiniteScroll)

    View Slide

  46. start
    entry attach
    listening
    finish
    SUCCESS [!hasMore]
    SUCCESS [hasMore]
    ERROR / error
    SCROLL [scrollPercentage > 0.9]
    READY
    fetching
    entry fetch
    entry detach

    View Slide

  47. class MyInfiniteScroll extends React.Component {
    attach() {}
    // render() {}
    }

    View Slide

  48. attach() {
    this.element.addEventListener(
    'scroll',
    this.handleScroll
    )
    }

    View Slide

  49. start
    entry attach
    READY
    SUCCESS [hasMore]
    listening
    finish
    SUCCESS [!hasMore] ERROR / error
    SCROLL [scrollPercentage > 0.9]
    fetching
    entry fetch
    entry detach

    View Slide

  50. this.props.transition('READY')

    View Slide

  51. ERROR / error
    SUCCESS [!hasMore]
    SUCCESS [hasMore]
    entry fetch
    fetching
    READY
    start
    entry attach
    listening
    finish
    SCROLL [scrollPercentage > 0.9]
    entry detach

    View Slide

  52. class MyInfiniteScroll extends React.Component {
    attach() {}
    fetch() {}
    // render() {}
    }

    View Slide

  53. fetch() {
    const { transition } = this.props
    loadData()
    .then(data => transition('SUCCESS', data)
    .catch(() => transition('ERROR'))
    }

    View Slide

  54. Workflow

    View Slide

  55. React
    Automata
    Transition
    (evt, data)
    Action
    Methods

    View Slide

  56. withStatechart(statechart, { devTools: true })(
    MyInfiniteScroll
    )

    View Slide


  57. Loading…

    View Slide

  58. “The best testing strategy
    is not writing tests.”
    Michele Bertoli, 2016

    View Slide

  59. testStatechart({ statechart }, MyInfiniteScroll)

    View Slide

  60. exports[`fetching`] = `

    Loading...

    `;

    View Slide

  61. exports[`error`] = `

    Something went wrong

    `;

    View Slide

  62. Benefits
    ● Fewer bugs
    ● Easy to understand
    ● What vs when

    View Slide

  63. “2018 front-end trend prediction:
    Everybody's going to start using
    state machines for UIs.”
    Max Stoiber, 2018

    View Slide

  64. bit.ly/automata-calculator

    View Slide

  65. Takeaways
    ● States > Transitions
    ● Top-down
    ● Read more papers

    View Slide

  66. Constructing the User
    Interface with
    Statecharts
    Ian Horrocks, 1998
    bit.ly/statecharts-book
    Statecharts: A Visual
    Formalism for
    Complex Systems
    David Harel, 1987
    bit.ly/statecharts-paper

    View Slide

  67. T
    @gandellinux
    @DavidKPiano
    @ryanflorence
    @mogsie

    View Slide

  68. @MicheleBertoli

    View Slide