Introduction

React Hooks were introduced in version 16.8.0. They are a complete departure from class component lifecycle events.

Hooks are basically functions (special ones) that let you “hook into” React features like state and lifecycle features from function components.

Hooks enable you to maintain state and handle side effects in functional components. Before hooks functional components were considered dumb or stateless components as they always have the same output for same input(no side effects).

Rules of Hooks

The following the are rules of hooks provided by React docs which are also used by the linter:

<aside> ⚠️ We can't use hooks in conditionals but we can use conditionals in the function of hooks.

</aside>

React relies on the order in which Hooks are called to know which state corresponds to which useState call. As long as the order of the Hook calls is the same between renders, React can associate some local state with each of them. That’s why hooks are not allowed inside conditionals.

<aside> 💡 React provide a linter plugin to enforce these rules automatically. So not following these rules will not break anything in react app if you are not using linter but they are considered good practice.

</aside>

useState

This is a function in which we pass the initial state that return an array which has the reactive state with current state value and a function to update the state.

The initialState argument is the state used during the initial render. In subsequent renders, it is disregarded. If the initial state is the result of an expensive computation, you may provide a function instead, which will be executed only on the initial render

During subsequent re-renders, the first value returned by useState will always be the most recent state after applying updates.

It’s similar to this.setState in a class, except it doesn’t merge the old and new state together.

<aside> ⚠️ useState is used to make a mutable state, and with change in that state the re-rendering happen.

</aside>

useState preserves the state value between the renders and then it triggers re-render.

Unlike this.setState in a class, updating a state variable always replaces it instead of merging it.

Function to update the reactive state.

Because React doesn't run setState synchronously there is a second argument that can optionally be passed to setState is a callback function which gets called immediately after the setState is completed and the components get re-rendered. This is used if we wanna do something after the state is updated.

But In state hooks there's nothing like the second argument callback function of setState. React automatically batches state updates in function components, and the "official" way to get rid of it is to use ReactDOM.flushSync().

useReducer

Reducer related concepts

useReducer() is a function in which we pass the reducer function and the initial state, and it return an array which has a reactive state we can share with UI and a dispatch function(which dispatches an action).

<aside> 📔 Reducer function takes in the old state and the action and return a new state. It must always return a state

</aside>

useEffect

useEffect, adds the ability to perform side effects from a function component.

It serves the same purpose as componentDidMount, componentDidUpdate, and componentWillUnmount in React classes, but unified into a single API. When you call useEffect, you’re telling React to run your “effect” function after flushing changes to the DOM.