Reactivity in

React and Vue

Edd Yerburgh

twitter @eddyerburgh

github.com/eddyerburgh

Similarities

  • View layer ✅
  • Component-based architecture ✅
  • Virtual DOM ✅

Differences

  • Reactivity

Components

const ExampleComponent = {
  template: `
      <div>
        <h1>0</h1>
      </div>
    `
}

Vue Component

new Vue({
  el: '#app',
  template: '<ExampleComponent />
})
const ExampleComponent = {
  render: createElement => {
    return createElement("div", [
      createElement("h1", 0)
    ]);
  }
};

Compiled component

The DOM

<div>
    <h1>0</h1>
</div>

HTML

<div>

<h1>

0

DOM

Updating the DOM is expensive 💰

The Virtual DOM

div
h1
0
Virtual DOM
const VNode = {
  type: "div",
  children: [
    {
      type: "h1",
      children: [
        {
          type: "text",
          value: "0",
          children: null
        }
      ]
    }
  ]
};

The virtual DOM in JavaScript

render()

Generate the virtual DOM

Update DOM

function patch(vNode){
  // ..
  if(!vNodeMatchesDOMNode) {
    DOMNode.replace(document.createElement(vNode.type))
  }
  //..
  vNode.children.forEach(child => updateDOM(child))
}

render VDOM

Update DOM

Initial render

State

<script>
  export default {
  template: `
      <div>
        <h1>0</h1>
      </div>
    `
  }
</script>
<template>
  <div>
    <h1>0</h1>
  </div>
</template>

<script>
  export default {
  }
</script>
<template>
  <div>
    <h1>{{count}}</h1>
  </div>
</template>

<script>
  export default {
    data: () => ({
      count: 0
    })
  }
</script>
<template>
  <div>
    <h1>{{count}}</h1>
    <button @click="count++">increment</button>
  </div>
</template>

<script>
  export default {
    data: () => ({
      count: 0
    })
  }
</script>

<div>

<button>

<h1>

0

DOM

increment

*click*

render()
div
button
h1
0
Virtual DOM
increment
1
div
button

div

<h1>

0

<button>

updateTextNode()

1

Increment

h1
1
Increment

state update

render VDOM

Update DOM

React

class Counter extends Component {
  constructor(props) {
    // ..
  }
  increment = () => {
    // ..
  };
  render() {
    return (
      <div>
        <h1>{this.state.count}</h1>
        <button onClick={this.increment}>increment</button>
      </div>
    );
  }
}
class Counter extends Component {
  // ..
  render() {
    return (
        React.createElement(
          "div",
          null,
          React.createElement("h1", null, this.state.count),
          React.createElement("button", { 
            onClick: this.increment }, "increment"),
          React.createElement(ImageComponent, null)
        );
    );
  }
}
class Counter extends Component {
  constructor(props) {
    this.state = {
      count: 0
    };
  }
  increment = () => {
    this.setState({
      count: this.state.count++
    });
  };
  render() {
    // ..
  }
}
setState({
  count: this.state.count++
})

Vue

count++
let a = 3;

const state = {
  set a(newValue) {
    a = newValue
    console.log(`set ${a}`)
  }
}

state.a = 5 // logs set 5
state.a = 7 // logs set 7
let a = 3;

const state = {
  // ..
  get a() {
    console.log(`get ${a}`)
    return a
  },
}

const component = {
  count: state.a
}

// logs get 3
function job() {
  activeJob = job
  update()
  activeJob = null
}

job()

state.a = 12

Thank you

Made with Slides.com