Viscera of React

Table of contents

  1. What is React?

  2. From components to elementsΒ 

  3. The problem

  4. The solution


What is React?

React is...Β 

"A JavaScript library for building user interfaces"

React !== React DOMΒ 

import React from 'react'
import ReactDom from 'react-dom'
import { Pressable } from 'react-native'

From components to elements

function Greetings(){
  return [
            <StyledHeader color="rebeccapurple">
              Hello from functional component 
            </StyledHeader>
            <div>
              <span>I will be a text node soon 😎</span>
            </div>
         ]
}
return [
          React.createElement(
          /* type */ StyledHeader,
          /* props */ { color: 'rebeccapurple' },
          /* children */ 'Hello from functional component'),

          React.createElement(
          'div',
           null,
          	React.createElement(
             	'span', 
              	 null, 
             	'I will be a text node soon 😎'))  
       ]

=

{
    type: StyledHeader,
    props: {
      color: 'rebeccapurple',
      children: 'Hello from functional component',
    },
    key: null,
    ref: null,
    $$typeof: Symbol.for('react.element')
  },
    
  {
    type: 'div',
    props: {
      children:  {
            {
            type: 'span',
            props: {
              children: 'I will be a text node soon 😎'
            },
            key: null,
            ref: null,
            $$typeof: Symbol.for('react.element')
            }
      },
    },
    key: null,
    ref: null,
    $$typeof: Symbol.for('react.element')
    }

React element

$$typeof: 0xeac7

React's render path

Β  Β tate as 1st class citizen

Transformation
Abstraction
Composition
State
Memoization
Lists
Continuations
State map
Memoization map
Algebraic effects
v = fn(data)

The problem

function fib(n) {
  if (n < 2) return n;

  return fib(n - 1) + fib (n - 2);
}

console.log(fib(3));

The problem

function a(){
 console.log("I do not have access to b's exec context");
 b();
};

function b(){
  console.log("I have an access to a's exec context");
}

The problem

  • Assign priority to different types of work
  • Pause work and come back to it later
  • Abort work if it’s no longer needed
  • Reuse previously completed work

FIBER

I still can't get it πŸ‘΅

πŸ§˜β€β™€οΈ πŸ§˜πŸ»β€β™€οΈ πŸ§˜πŸΌβ€β™€οΈ πŸ§˜πŸ½β€β™€οΈ πŸ§˜πŸΎβ€β™€οΈ πŸ§˜πŸΏβ€β™€οΈ πŸ§˜β€β™‚οΈ πŸ§˜πŸ»β€β™‚οΈ πŸ§˜πŸΌβ€β™‚οΈ

Components tree you've written using JSX
Elements react created after calling render
Corresponding fiber nodes

We are callable( )

We are IMMUTABLE

We are mutable

Example

function Counter() {
  const [count, setCount] = React.useState(0);
  const isVisible = count < 2;
  return [
      <button key="0" onClick={() => setCount(count + 1)}>Increment</button>,
      <span key="1">{count}</span>,
      {isVisible && <span key="2">Make me disappear</span>}
]

const container = document.querySelector('#app');
ReactDOM.render(<Counter/>, container);

https://codesandbox.io/s/for-lulz-e61kr?file=/src/App.js

The Component

function Counter() {
  const [count, setCount] = React.useState(0);
  const isVisible = count < 2;
  return [
      <button key="0" onClick={() => setCount(count + 1)}>Increment</button>,
      <span key="1">{count}</span>,
      {isVisible && <span key="2">Make me disappear</span>}
]

The Component w/o JSX

...
return  [
      React.createElement(
        'button',
        {
            key: '0',
            onClick: () => setCount(count+1)
        },
        'Increment'
    ),
    React.createElement(
        'span',
      	{
           key="1"
        },
         count
    ),
     React.createElement(
        'span',
        {
           key="2"
        },
        'Make me disappear'
    )]

The Element

  {
      $$typeof: Symbol(react.element),
      type: 'button',
      props: {
          key: '0'
          children: 'Increment',
          onClick: () => { ... }
      }
  },
  {
      $$typeof: Symbol(react.element),
      type: 'span',
      props: {
          key: '1'
          children: 0
      }
  },
  {
      $$typeof: Symbol(react.element),
      type: 'span',
      props: {
          key: '2'
          children: 'Make me disappear'
      }
  }

Host Root

Counter

child

return

child

return

Button

Span

Span

sibling

{
    stateNode: Counter(),
    type: Counter,
    alternate: null,
    key: null,
    updateQueue: null,
    memoizedState: {count: 0},
    pendingProps: {},
    memoizedProps: {},
    tag: 0,
    effectTag: 0,
    nextEffect: null
}
{
    stateNode: new HTMLSpanElement,
    type: "span",
    alternate: null,
    key: null,
    updateQueue: null,
    memoizedState: null,
    pendingProps: {children: 0},
    memoizedProps: {children: 0},
    tag: 5,
    effectTag: 0,
    nextEffect: null
}
{
    stateNode: new HTMLSpanElement,
    type: "span",
    alternate: null,
    key: null,
    updateQueue: null,
    memoizedState: null,
    pendingProps: {children: 'Make me disappear'},
    memoizedProps: {children: 'Make me disappear'},
    tag: 5,
    effectTag: 0,
    nextEffect: null
}
// each of shown fiber
// nodes has following properties
{
  child: []
  return:
  sibling:
}

Host Root

Counter

Button

Span

Span

<span> 2 </span>

<span>Make me...</span>

Stack version

Host Root

Counter

Button

Span

Span

<span> 3 </span>

<span>Make me...</span>

Stack version

Host Root

Counter

Button

Span

<span> 3 </span>

<span>Make me...</span>

Stack version

<span>Make me...</span>

Phases

<span>Make me...</span>

Phase 1

render / reconcilation

<span>Make me...</span>

Phase 1

render / reconcilation

<span>Make me...</span>

Phase 1

render / reconcilation

Phase 2

commit

Current 
Host Root
Counter
Button
Span
Span
+1

update queue

Current 
Work in progress
Host Root
Host Root
Counter
Button
Span
Span
+1

update queue

copy

Current 
Work in progress
Host Root
Host Root
Counter
Button
Span
Span
+1

update queue

Counter
+1

update queue

copy

Current 
Work in progress
Host Root
Host Root
Counter
Button
Span
Span
+1

update queue

Counter
Button
Span
Span

nextEffect

firstEffect

nextEffect

  • [UNSAFE_]componentWillMount (deprecated)
  • [UNSAFE_]componentWillReceiveProps (deprecated)
  • getDerivedStateFromProps
  • shouldComponentUpdate
  • [UNSAFE_]componentWillUpdate (deprecated)
  • render
Render/ reconcile phase
  • getSnapshotBeforeUpdate
  • componentDidMount
  • componentDidUpdate
  • componentWillUnmount
Commit phase

Thank you!

Q&A

Viscera React

By Kostiantyn Synyshyn

Viscera React

How React works under the hood

  • 30