$30 off During Our Annual Pro Sale. View Details »

Understanding React

Understanding React

Raphael Amorim

June 08, 2018
Tweet

More Decks by Raphael Amorim

Other Decks in Technology

Transcript

  1. WRITING
    YOUR
    OWN 

    REACT
    RENDERER
    @ R A P H A M O R I M S

    View Slide

  2. WHO THE HELL IS THIS GUY?

    View Slide

  3. View Slide

  4. Sim!

    Sou o moleque
    que chegou
    atrasado!

    View Slide

  5. View Slide

  6. View Slide

  7. Software Developer Engineer @godaddy
    JS Foundation Member @jquery
    Maintainer React-TV
    Raphael Amorim
    Previously @globocom, @petrobras
    22 years old
    Mozillian
    Metido a besta

    View Slide

  8. View Slide

  9. View Slide

  10. Não tem desconto
    na compra do domínio!

    View Slide

  11. React
    @ R A P H A M O R I M S

    View Slide

  12. difference between
    components,
    their instances,
    and elements in React

    View Slide

  13. For example,
    you may declare a
    Button component
    by creating a class.

    View Slide

  14. When the program is running,
    you may have several instances
    of this component on screen,
    each with its own properties and
    local state.

    View Slide

  15. This is the traditional
    object oriented UI programming.

    View Slide

  16. And why introduce elements?

    View Slide

  17. In this traditional UI model,
    it is up to you take care of
    creating and destroying child
    component instances.

    View Slide

  18. If a Form component wants to render
    a Button component.
    It needs to create its instance, and
    manually keep it up to date with
    any new information.

    View Slide

  19. class Form extends TraditionalObjectOrientedView {
    render() {
    // Read some data passed to the view
    const { isSubmitted, buttonText } = this.attrs;
    if (!isSubmitted && !this.button) {
    // Form is not yet submitted. Create the button!
    this.button = new Button({
    children: buttonText,
    color: 'blue'
    });
    this.el.appendChild(this.button.el);
    }
    if (this.button) {
    // The button is visible. Update its text!
    this.button.attrs.children = buttonText;
    this.button.render();
    }
    if (isSubmitted && this.button) {
    // Form was submitted. Destroy the button!
    this.el.removeChild(this.button.el);
    this.button.destroy();
    }
    . . .

    View Slide

  20. Each component has to keep
    references to its DOM node and to
    the instances of the children
    components, and create, update,
    and destroy them when the time is
    right.

    View Slide

  21. Now let’s talk about React.

    View Slide

  22. In React, this is where
    the elements come to rescue.

    View Slide

  23. An element is a plain
    object describing a component
    instance or DOM node and its
    desired properties.

    View Slide

  24. It contains only information
    about the component type
    (for example, a Button),
    its properties
    (for example, its color),
    and any child elements inside it.

    View Slide

  25. An element is not an actual instance.
    Rather, it is a way to tell React:
    What you want to see
    on the screen

    View Slide

  26. You can’t call any methods on the element.
    It’s just an immutable description object with
    two fields:
    type: (string | Component)
    props: Object.*

    View Slide

  27. You can’t call any methods on the element.
    It’s just an immutable description object with
    two fields:
    type: (string | Component)
    props: Object.*

    View Slide

  28. When the element’s type is a string, an element
    represents a DOM node with that tag name,
    and props correspond to its attributes.
    This is what React will render. For example:

    View Slide

  29. {
    type: ‘button',
    props: {
    className: 'button button-blue',
    children: {
    type: 'b',
    children: 'OK!'
    }
    }
    }

    View Slide



  30. OK!


    View Slide

  31. By convention, when we want to create an
    element tree, we specify one or more child
    elements as the children prop of their
    containing element.

    View Slide

  32. What’s important is that both child and
    parent elements are just descriptions
    and not actual instances

    View Slide

  33. They don’t refer to anything on the screen
    when you create them. You can create them
    and throw them away, and it won’t matter
    much.
    really…
    React-DOM, React-Hardware, React-Native, React-TV […] does it.

    View Slide

  34. React Elements are easy to traverse, don’t
    need to be parsed, and of course are
    much lighter than the actual DOM
    elements.

    View Slide

  35. they’re just objects!

    View Slide

  36. However, the type of an element can also
    be a function or class corresponding to a
    React component.

    View Slide

  37. {
    type: Button,
    props: {
    color: 'blue',
    children: 'OK!'
    }
    }

    View Slide

  38. This is the core idea of React.

    View Slide

  39. An element describing a component is
    also an element, just like an element
    describing the DOM node.
    They can be nested and mixed with each
    other.

    View Slide

  40. This feature lets you define
    a OkButton component as a Button
    with a specific color property value.
    Without worrying about
    whether Button renders to a button,
    a div, or something else entirely.

    View Slide

  41. const ConfirmButton = ({ children }) => ({
    type: Button,
    props: {
    color: ‘green',
    children: children
    }
    });

    View Slide

  42. const CreateAccount = () => ({
    type: 'div',
    props: {
    children: [{
    type: 'p',
    props: {
    children: ‘Welcome to Nubank!’
    }
    }, {
    type: ConfirmButton,
    props: {
    children: ‘Yahooo!'
    }
    }, {
    type: Button,
    props: {
    color: 'red',
    children: 'Cancel'
    }
    }]
    });

    View Slide

  43. const CreateAccount = () => (

    Welcome to Nubank
    Yahooo!
    Cancel

    );

    View Slide

  44. When React sees an element with a function
    or class type,
    it will know to ask that component what
    element it renders to with the given props.

    View Slide

  45. {
    type: Button,
    props: {
    color: 'blue',
    children: 'OK!'
    }
    }

    View Slide

  46. React will ask Button what it renders to,
    and it will get:

    View Slide

  47. {
    type: 'button',
    props: {
    className: 'button button-blue',
    children: {
    type: 'b',
    children: 'OK!'
    }
    }
    }

    View Slide

  48. React will repeat this process until it knows the
    underlying DOM tag elements for every
    component on the page.

    View Slide

  49. const Form = ({ isSubmitted, buttonText }) => {
    if (isSubmitted) {
    // Form submitted! Return a message element.
    return {
    type: Message,
    props: {
    text: 'Success!'
    }
    };
    }
    // Form still visible! Return a button element.
    return {
    type: Button,
    props: {
    children: buttonText,
    color: 'blue'
    }
    };
    };

    View Slide

  50. The returned element tree can contain both
    elements describing DOM nodes, and elements
    describing other components.
    This lets you compose independent parts of UI
    without relying on their internal DOM structure.

    View Slide

  51. We let React create, update, and destroy instances.

    View Slide

  52. We describe them with elements we return from the
    components, and React takes care of managing the
    instances.

    View Slide

  53. In the last code, Form, Message, and Button are
    React components.
    They can either be written as functions, as above, or
    as classes descending from React.Component:

    View Slide

  54. class Button extends React.Component {
    render() {
    const { children, color } = this.props;
    // Return an element describing a
    // {children}
    return {
    type: 'button',
    props: {
    className: 'button button-' + color,
    children: {
    type: 'b',
    props: {
    children: children
    }
    }
    }
    };
    }
    }

    View Slide

  55. When a component is defined as a class, it is a little
    more powerful than a functional component.
    It can store some local state and perform custom
    logic when the corresponding DOM node is created
    or destroyed.

    View Slide

  56. A functional component is less powerful but is
    simpler, and it acts like a class component
    with just a single render() method.

    View Slide

  57. However, whether functions or classes,
    fundamentally they are all components to React.
    They take the props as their input, and return the
    elements as their output.

    View Slide

  58. ReactDOM.render({
    type: Form,
    props: {
    isSubmitted: false,
    buttonText: 'OK!'
    }
    }, document.getElementById('root'));

    View Slide

  59. At the end of this process React knows the result DOM
    tree, and a renderer like ReactDOM or React
    Native applies the minimal set of changes necessary to
    update the actual DOM nodes.

    View Slide

  60. Extracted from:


    https://medium.com/@dan_abramov/react-
    components-elements-and-instances-90800811f8ca

    View Slide

  61. Reconciliation
    @ R A P H A M O R I M S

    View Slide

  62. React provides a declarative API so
    that you don’t have to worry about
    exactly what changes on every
    update.

    View Slide

  63. Tl;dr;


    React’s “diffing” algorithm so that
    component updates are predictable
    while being fast enough for high-
    performance apps.

    View Slide

  64. render()

    View Slide

  65. Based on current props and
    initialState.

    View Slide

  66. Create a tree of React elements.

    View Slide

  67. Render is based on number of
    elements in the tree.
    O(n3)

    View Slide

  68. displaying 1000 elements
    ===
    one billion comparisons

    View Slide

  69. React implements a heuristic O(n)
    algorithm based on two
    assumptions:

    View Slide

  70. 1.Two elements of different types will produce different
    trees.

    View Slide

  71. 2. The developer can hint at which child elements
    may be stable across different renders with
    a key prop.

    View Slide

  72. Elements Of Different Types

    View Slide

  73. Going from to , or from to , or
    from to - any of those will lead to a full
    rebuild.

    View Slide

  74. When tearing down a tree, old DOM nodes are
    destroyed.

    View Slide

  75. Component instances receive componentWillUnmount().
    When building up a new tree, new DOM nodes are
    inserted into the DOM.
    Component instances receive componentWillMount() and
    then componentDidMount().
    Any state associated with the old tree is lost.

    View Slide

  76. Component instances receive componentWillUnmount().
    When building up a new tree, new DOM nodes are
    inserted into the DOM.
    Component instances receive componentWillMount() and
    then componentDidMount().
    Any state associated with the old tree is lost.

    View Slide







  77. View Slide

  78. DOM Elements Of The Same Type

    View Slide

  79. React looks at the attributes of both,
    keeps the same underlying DOM node,
    and only updates the changed
    attributes

    View Slide

  80. 'bold'}} />
    'bold'}} />

    View Slide

  81. Recursing On Children

    View Slide

  82. By default, when recursing on the children
    of a DOM node, React just iterates over
    both lists of children at the same time and
    generates a mutation whenever there’s a
    difference.

    View Slide


  83. first
    second


    first
    second
    third

    View Slide

  84. If you implement it naively, inserting an
    element at the beginning has worse
    performance.

    View Slide


  85. Neymar
    Firmino


    Jesus
    Neymar
    Firmino

    View Slide

  86. React will mutate every child.

    View Slide

  87. Keys

    View Slide

  88. In order to solve this issue, React supports
    a key attribute.

    View Slide

  89. When children have keys, React uses the
    key to match children in the original tree
    with children in the subsequent tree.

    View Slide


  90. Neymar
    Firmino


    Jesus
    Neymar
    Firmino

    View Slide

  91. Now React knows that the element with
    key '9' is the new one, and the elements
    with the keys '10' and '20' have just
    moved.

    View Slide

  92. https://reactjs.org/redirect-to-codepen/
    reconciliation/index-used-as-key

    View Slide

  93. Tradeoffs

    View Slide

  94. Keys should be stable, predictable, and
    unique. Unstable keys (like those produced
    by Math.random()) will cause many
    component instances and DOM nodes to
    be unnecessarily recreated.

    View Slide

  95. The algorithm will not try to match subtrees
    of different component types.

    View Slide

  96. React-Reconciler
    @ R A P H A M O R I M S

    View Slide

  97. View Slide

  98. React provides a declarative API so
    that you don’t have to worry about
    exactly what changes on every
    update.

    View Slide

  99. I would like to announce
    something that I’m working on!

    View Slide

  100. github.com/raphamorim/
    react-ape

    View Slide

  101. View Slide

  102. github.com/raphamorim/

    react-dog-renderer
    @raphamorims

    View Slide

  103. O correto é bixxxxxcoito.
    Thanks everybody.
    @raphamorims

    View Slide