Deep dive in Reactjs

Deep dive in Reactjs

How react works internally.

One question that often crosses our mind,how does react work internally,we know we can create components using jsx and render them on web but how does this happen, what makes react so fast and flexible? we will today learn all those things responsible for this such as Reconciliation,Virtual DOM,Diffing algorithm,special property key and how react communicates with renderers.

Today we will look at basic concepts that makes react what it is today.

Before going forward,we need to understand difference between

1-React Component

2-React Element

3-React Instances

React Components

This is a simple App component which returns react element but browser does not understand jsx so it gets converted to something like this under the hood by babel which we can see by doing console of App().

the return value of App() function

Components can be class based and function based both.

Lets analyse what is happening here

1- firstly JSX gets converted into React.createElement function call

2- Each of them returns object similar to one seen in above image .

3-In our case object represents root value of type div

we can see different properties here lets look at them

$$typeof is used for security purposes ,here key and ref are null because we havent provided them a value ,interesting things to note here are type and props so div is type of property here which corresponds to html element and props which contains all of the children, in our case children is nothing but simple text of "App component"

React Elements

lets look at how does React.createElement function looks like

here div is element and also type ,this type can also be paragraph or button these react elements can contain several other elements inside them, and form element tree which is then rendered by react component

As seen in above images when we console logged App() it gives us a object but we dont call any component while rendering we just use them as <App/> so what happens here ?

lets console log this and find out

when we do console.log(<App/>)

Here,we see some similar result as we got when in image 2 but difference is type which is a function

earlier type was of div when we called it and now it has type of function ,it is to be noted that react call these components internally

Component Instance

When react element describes a component it keeps track of it and creates a component instance with each instance having their own lifecycle and internal state which are very familiar to us

in functional component we can access them using hooks ,for eg-

1- const[state,setState]=useState();

2- useEffect(()=>{

// do something

})

in class component system we use predefined methods and this keyword

1- componentDidMount(){

// after component mounts

}

2- componentWillUnmount(){

// before component unmounts

}

Reconciliation

We know that all React does is create a tree of elements.This all happens when we call the render() method .React skins recursively from top to bottom through every element present and calls components defined in between ,react keeps history of elements in memory and it is called as virtual DOM ,let us look how this looks as via a image.

Let us take look at our simple component

Whenever we make change in our App component it gets reflected as

This purple line text indicates that we have made changes in our <div> which is inside our head .

The next thing is to sync virtual DOM with real DOM, During the initial render react has no way than to insert full tree,but wont it be too time consuming and costly to render new tree again and again over small changes well react compares the two trees and finds smallest number of operations to transform one tree to another.this is handled using Difffing algorithm,under normal conditions it would take n^3 operations for n elements but because of diffing algo react manages to do it in <=n number of oprations

Diffing Algorithm.

Diffing algo works on two different assumptions-

1- Two elements of different types will produce different trees

2- When we have list of child elements which often changes ,than we should provide unique "key" as a prop

for first assumption you may think isnt it obvious and generally speaking not so much, but in react it is completely fine,previously I told you that key isnt part of prop and this explains why because it has special place in Diffing algorithm and key always needs to be unique

Change in components -

Reacts destroys all component instances in the old tree along with their current state and we term this as component unmount

Change in attributes-

React simply updates those attributes and state is maintained

Change in children-

<ul>
<li>john</li>
<li>martin</li>
</ul>

lets assume this changes to 
<ul>
<li>john</li>
<li>martin</li>
<li>Tom</li>
</ul>

React notices here that a new entry is added to tree and that too after two entries which were present there already and hence does not generate a new tree but if we add new entry at top then will react rerender it again ? this problem is solved using key property which is assigned specially to each element and key is always unique so react matches keys first and sees if there is new entry and then works accordingly,this is same reason why key isnt a prop and has special use.

Rendering

Rendering in reactjs is handled by rendering packages called renderers for ex-React DOM,react on its own only allows us to define components,elements and also does the diffing part ,it isnt plattform specific and doesnt take care of rendering.Most of implementation lives in renderers the insertion of tree is done by renderers and so they are different packages,react does not even know that elements end up on browsers,therefore reactjs is compatible with any renderer,

infact we can create our own renderer using the react-test-renderer package

you may wonder we only import ReactDOM.render() once and still it has so many implementation in it ,so how can so much implementation live in renderer package lets answer this

This happens through communication of Reactjs with renderer

There are many ways for communication of react with renderers one such is setState() of class based component but as far as current practices include after introduction of functional components one such example of communication is via a usestate hook

const React= {
//
__currentDispatcher:null,

useState(initialState){
return React.__currentDispatcher.useState(initialState);

},

}

we can see when we call useState here ,then call is forwarded to something called as currentDispatcher and this dispatcher is once again set by React DOM ,it is set to something like this when we call any component

const previousDispatcher = React.__currentDispatcher;
React.__currentDispatcher = ReactDOMDispatcher ;

let result ;
try {
result = Component(props);
} finally {
React.__currentDispatcher = previousDispatcher ;

Here also we can see currentDispatcher is being set by ReactDOM but this time component is called because it is a function

This is how Reactjs communicates with renderes .

I hope I was able to clear some insights about how react works , opinions and help of yours is always appreciated.