useState
is a react hook which allows you to add a state variable to a react component.
The syntax of useState
hook looks like this: const [variable, setVariable] = useState();
But what is a state?
Components in React can change the UI on the screen based on some changes in state variables. For example on a shopping website, clicking on BUY should take me to the checkout page or add the item to a cart. When I click on the BUY button, the icon of the cart should update ๐ with the number of items in it. To do this, the CART component needs to know what the number was before, and then add +1 to it. This is a component-specific memory in React, which is called the State.
But why can't we use regular variables?
State variables are also responsible for re-rendering the component when they are changed. This updates the UI you see on the screen to view the new state of the component. Regular variables do not trigger re-renders so they are not able to update the UI. Below is a code snippet example of such.
For React to update a component, 2 things are required.
A variable that retains the data between renders
A trigger that tells React to re-render a specific component.
Regular variables don't do this and they will get reset to default values. A useState
hook returns 2 things and using array destructuring we have the following
Now we have set the flow that useState
can set a state variable and trigger React to re-render to update a component.
But how does the re-rendering happen behind the scenes?
Re-rendering in React: behind the scenes
React here uses a process called reconciliation when it needs to update a component to reflect the changed state in its UI.
Virtual Document Object Model (VDOM) aka Virtual DOM is used to perform reconciliation by comparing the component's current and previous state. React keeps a twin copy of DOM known as VDOM. When we make changes or add new data to the state variable, React creates a new Virtual DOM and compares it with the previous one. After that, it updates the DOM with the least number of changes possible.
Using this way the changes in a React website are almost instant and fast. This gave a major performance boost to updating UI when working with React.
There are 2 important things to understand about re-rendering components
Fiber reconciliation algorithm
Diffing algorithm
Fiber Reconciliation Algorithm
This is a new reconciliation algorithm adopted by React 16.0 and further versions aiming to improve the performance of React applications by providing a better reconciliation process.
The problem with reconciliation algorithms before React 16.0 was that it was becoming inefficient in certain use-cases. For instance, if a component has many elements that need to be updated on a change of state variable, it would take a long time to process resulting in the application freezing.
The Fiber algorithm divides the work into smaller parts known as Fibers.
A fiber represents a single element in the Virtual DOM tree and performs a reconciliation process on each one individually. This way React can give priority to certain fibers to be processed first and keep the rest for later. Like updating the components that are visible to the user first and reconciling the remaining fibers later. This way the UI of the application doesn't freeze at all.
Let's consider the code written in the above code snippet again. When we look at the console.log("Element", element)
we get something like this
This object represents a Virtual DOM and you can see it in the user interface. In a tree representation, it will look something like this and after the Increment
button is clicked
Fiber here works by maintaining a linked list of fibers. Each represents a single element of the VDOM and has additional information as presented in the screenshot above like type, props and current state. When the state changes, React creates a new tree to reflect the changes and compares it with the previous one.
Now it can pause and prioritise the reconciliation process for the different elements of the tree and find the shortest way to update the UI.
Diffing Algorithm
How does React find the minimum number of steps to update the component UI?
Diffing algorithm is a part of the fiber framework that is used to determine the minimum number of steps required to update the DOM. It works by recursively comparing the elements of VDOM of the old and new component state which identifies the differences.
The algorithm compares the nodes first. If the nodes are not the same as before, it will consider that the VDOM tree has changed and update with new nodes. But, if the nodes are the same as before then it moves to compare the attributes and children nodes. The attributes can include the node type, props and current state of the component.
In this approach, you can think Diffing algorithm as a Breath First Search algorithm as it traverses the tree level by level comparing the nodes and their attributes. This method is efficient because it will compare the sibling nodes too and can replace the subtree if changes are detected.
Based on such differences identified, it generates a set of changes that need to be performed to sync the DOM to the latest state with the minimum number of steps in React.