Table of contents
Hooks in React
In React, a hook is a function that allows you to use state and other React features in functional components. Hooks were introduced in React 16.8 as a way to write reusable and stateful logic in functional components. In React we have several built-in Hooks like useState, useEffect, useContext, etc.
useState Hook Implementation
A simple implementation of the "useState" Hook in React:
Note: This will work for only one state, for more we need an array.
const React = (function () {
let _val;
function useState(initVal) {
const state = _val || initVal;
console.log("useState called");
const setState = (newVal) => (_val = newVal); //setter function
return [state, setState];
}
function render(Component) {
const C = Component();
C.render();
return C;
}
return { useState, render };
})();
function Component() {
const [index, setIndex] = React.useState(0);
return {
render: () => console.log("index: ", index),
setIndex: () => setIndex(index + 1),
};
}
let App = React.render(Component);
App.setIndex();
App = React.render(Component);
App.setIndex();
App = React.render(Component);
App.setIndex();
App = React.render(Component);
App.render();
Output
Explanation
const React = (function () { ... })();
: declares a constant namedReact
and assigns it the result of an immediately invoked function expression (IIFE). The purpose of this IIFE is to create a closure and encapsulate theuseState
andrender
functions.Inside the IIFE, we have the following code:
let _val;
: This line declares a variable_val
in the function scope. It will be used as a private variable shared among components.function useState(initVal) { ... }
: This is theuseState
function implementation. It initializes thestate
variable with the current_val
or theinitVal
passed as an argument. It also defines thesetState
function, which sets the_val
to the new value provided. Finally, it returns an array containing thestate
andsetState
functions.function render(Component) { ... }
: This is therender
function implementation. It takes aComponent
function as an argument. It invokes theComponent
function, which is expected to return an object with arender
method. It callsC.render()
to execute therender
method of theComponent
and returns theComponent
object.Finally, the IIFE returns an object containing the
useState
andrender
functions.
function Component() { ... }
: This is a sample component function that is meant to be rendered by therender
function. It defines auseState
call, which retrieves thestate
andsetState
functions from theReact
object. TheComponent
function returns an object with arender
method and asetIndex
method. Therender
method logs the currentindex
value to the console, and thesetIndex
method increments theindex
by 1.let App = React.render(Component);
: This line calls theReact.render
function with theComponent
function as an argument. It assigns the returned value to theApp
variable. TheApp
object should have arender
method.App.setIndex();
: This line calls thesetIndex
method on theApp
object, incrementing theindex
value by 1.App = React.render(Component);
: This line re-renders theComponent
using theReact.render
function and assigns the new result to theApp
variable.Steps 5 and 6 are repeated multiple times to demonstrate how the state is preserved and updated across multiple renders.
_val
forms a closure. A closure is a combination of a function and the lexical environment within which that function was declared. In this case, the useState
function has access to the _val
variable because it is declared in the outer function scope.
Each time the useState
function is invoked, it references the same _val
variable declared in the outer scope. This allows the state to be preserved between multiple invocations of the useState
function and across different renders of the Component
.
Hope you found this helpful.
Definitely you should checkout the video: https://www.youtube.com/watch?v=KJP1E-Y-xyo