<Build Your Own React/>

Ofir Dagan

@ofirdagan2

ofird@wix.com

<Ofir Dagan/>

Ofir Dagan

@ofirdagan2

ofird@wix.com

  • Team Lead @ Wix.com
  • React Native + FED
  • Podcast Addict
  • Love Adrenaline

Syntax Sync

React.createElement('div', null, `Sveika pasaule`);
<div>Sveika pasaule</div>
React.createElement(
  'div',
  {className: 'title'},
 `Sveika pasaule`
);
<div className="title">
    Sveika pasaule
</div>
React.createElement(
  'div',
  {className: 'wrapper'},
  React.createElement(Person, {age: 56}, null),     
  React.createElement(Person, {age: 65}, null)
);
<div class="wrapper">
    <Person age="56"/>
    <Person age="65"/>
</div>

Before we build it we need to understand what it does

  • Basicly React is a library to build a dynamic tree (in our case DOM)

For Example

const helloWorld = React.createElement('div', null, `Sveika pasaule`);
ReactDOM.render(helloWorld, document.getElementById('root'));

Will (not) surprisingly result with

 +---+ element = div
     |
     |
     +--> children = [Sveika pasaule]

And now with props

const Hello = function ({name}) {
  return React.createElement('div', null, `Hello ${name}`);
};

const hello = React.createElement(Hello, {name: 'Ofir'}, null);
ReactDOM.render(helloWorld, document.getElementById('root'));


-> Hello Ofir
+---+  element = hello
    |
    |
    +---+  props = {name: 'Ofir'}
    |
    |
    +--+> children = [div]
                       |
                       |
                       +--> children = [Hello Ofir]

And when the props become dynamic... we call it state

class Hello extends React.Component {
  constructor() {
    super();
    this.state = {};
    this.fetchName();
  }
  
  fetchName() {
    setTimeout(() => this.setState({name: 'Latvia'}), 500);
  }
  
  render() {
    return React.createElement('div', null, `Hello ${this.state.name}`);
  }
}


const helloWorld = React.createElement(Hello, null, null);
ReactDOM.render(helloWorld, document.getElementById('root'));

Output
------
-> Hello undeifned
--- 500ms passes
-> Hello Latvia

React Examples #1

class NameComponent extends React.Component {
  render() {
    return (      
      <h1>Hello {this.props.name}</h1>      
    );
  }
}

React.render(
  <NameComponent name="Boki"/>,
  document.getElementById('root')
);

-> Hello Boki

React Examples #2

class NameComponent extends React.Component {
  constructor(props) {
    super(props);
    this.props.name = 'Foo'; // ----------- NEW LINE ---------------
  }
  
  render() {
    return (      
      <h1>Hello {this.props.name}</h1>      
    );
  }
}

React.render(
  <NameComponent name="Boki"/>,
  document.getElementById('root')
);

-> Hello Foo

React Examples #3

class NameComponent extends React.Component {
  constructor(props) {
    super(props);
    this.props.name = 'Foo';
    setTimeout(() => {
      this.props.name = 'Moki' // ----------- NEW LINE ---------------
    });
  }
  
  render() {
    return (      
      <h1>Hello {this.props.name}</h1>      
    );
  }
}

React.render(
  <NameComponent name="Boki"/>,
  document.getElementById('root')
);

-> Hello Foo

React Examples #4

class NameComponent extends React.Component {
  constructor(props) {
    super(props);
    this.props.name = 'Foo';
    setTimeout(() => {
      this.props.name = 'Moki'
      this.setState({bla: '1'});  // ----------- NEW LINE ---------------
    });
  }
  
  render() {
    return (      
      <h1>Hello {this.props.name}</h1>      
    );
  }
}

React.render(
  <NameComponent name="Boki"/>,
  document.getElementById('root')
);

-> Hello Moki

Now we can start!

Step #1 - Hello World

Great Success

Step #2 - Non DOM Elements AKA Components :)

Recap:

  • div
  • element
  • stateless component
  • dom children
  • react class

We rendered:

Step #3 - Props and State

Recap:

  • props support for stateless/class components
  • handled dom attributes (including class and style)
  • stateful components

We implemented:

Step #4 - JSX

 

<JSX/>

Step #5 - Complex Examples

Wait a minute... This doesn't seem so

efficient

And where is this "virtual dom" I keep hearing about

Time to face the truth 

Let's do some performance analysis

The Naive Algorithm

  • Clear the DOM
  • Render the root component
  • Replace all of the DOM nodes with new ones

A Better Algorithm

  • We're already in javascript realm
    (everything is written in js)
  • So instead of creating the DOM elements straight away let's keep a js tree object (basically json)
  • Apply the render on it
  • Read the real DOM 
  • Figure out the differences
  • Apply only the changes on the DOM

An Better Algorithm

  • We already calculated the full js tree which is the same as the DOM
  • So instead of diffing against the current DOM
  • On rerender create a new js tree (virtual DOM)
  • Diff between the two virtual DOMs (very very fast)
  • Figure the changes
  • Apply only the changes on the DOM

FIBER - The Next Generation

Other

React Renderers

Reading List and Inspirations for this talk

Thank You

Ofir Dagan

@ofirdagan2

ofird@wix.com

Build your own react 16:9

By ofird

Build your own react 16:9

  • 1,827