ReactJS Hooks

React Hooks are a new feature in React that allow you to use state and other React features in functional components. Prior to the introduction of Hooks, functional components were not able to have their own state or use other React features such as lifecycle methods. This meant that if you wanted to use state or other React features in a functional component, you had to convert it to a class-based component.

Hooks solve this problem by allowing you to use state and other React features in functional components without having to convert them to class-based components. This makes it easier to reuse code and keeps your component hierarchy flatter, which can make your application easier to understand and maintain.

There are several built-in Hooks in React, such as useState, useEffect, and useContext. Here's an example of how you can use the useState Hook to add state to a functional component:

import { useState } from 'react'; 
function MyComponent() { 
	const [count, setCount] = useState(0); 
	return (<div> <div>{count}</div> 
		<button onClick={() => setCount(count + 1)}>Increment</button> 

In this example, the useState Hook is used to add a state variable called "count" to the MyComponent component. The useState Hook returns an array with two elements: the current state value and a function that updates the state value. The MyComponent component uses the count variable to render the current count to the screen and the setCount function to update the count when the "Increment" button is clicked.

Here's an example of how you can use the useEffect Hook to perform a side effect in a functional component:

import { useEffect } from 'react'; 
function MyComponent() { 
	useEffect(() => { 
	console.log('Component rendered'); }); 
	return <div>Hello World</div>; 

In this example, the useEffect Hook is used to log a message to the console every time the MyComponent component is rendered. The useEffect Hook takes a function as an argument, which is called the "effect" function. The effect function is called after the component is rendered and can be used to perform side effects such as making API calls or subscribing to events.

Here are a few more things you might want to know about React Hooks:

  • You can use the useReducer Hook to manage complex state logic in functional components. The useReducer Hook is similar to the useState Hook, but it is designed for managing complex state logic. It works similarly to the reduce function in JavaScript, where you define a reducer function that takes the current state and an action and returns the new state. Here's an example of how you can use the useReducer Hook to add state logic to a functional component:
import { useReducer } from 'react'; 
function reducer(state, action) { 
	switch (action.type) { 
		case 'increment': return { count: state.count + 1 }; 
		case 'decrement': return { count: state.count - 1 }; 
		default: throw new Error(); 

function Counter() { 
	const [state, dispatch] = useReducer(reducer, { count: 0 }); 
	return ( <div> 
		<button onClick={() => dispatch({ type: 'increment' })}>Increment</button> 
		<button onClick={() => dispatch({ type: 'decrement' })}>Decrement</button> 
		</div> ); 

In this example, the useReducer Hook is used to add state logic to the Counter component. The component has a reducer function that defines how the state should be updated based on different actions. The component also has two buttons that, when clicked, dispatch actions to the reducer to update the state.

  • You can use the useContext Hook to access context in functional components. The useContext Hook allows you to access context in a functional component by taking a context object as an argument and returning the current context value. Here's an example of how you can use the useContext Hook:
import { useContext } from 'react'; 
const MyContext = React.createContext(); 

function MyComponent() { 
	const value = useContext(MyContext); 
	return ( <div>{value}</div> ); 

In this example, the MyComponent component is using the useContext Hook to access the value of the MyContext

  • You can use custom Hooks to reuse stateful logic between components. Custom Hooks are functions that start with the word "use" and can call other Hooks. This allows you to extract stateful logic from a component and reuse it in other components. For example, you could create a custom Hook called useFetch to handle making API calls in multiple components like this:
import { useState, useEffect } from 'react'; 
function useFetch(url) { 
	const [data, setData] = useState(null); 
	const [loading, setLoading] = useState(true); 
	const [error, setError] = useState(null); 
	useEffect(() => { 
		async function fetchData() 
			try { 
				const response = await fetch(url); 
				const data = await response.json(); 

			catch (error) { 

			finally { 
	}, [url]); 
	return { data, loading, error }; 

In this example, the useFetch custom Hook handles making an API call to the specified URL and storing the data, loading state, and error state in the component's state. You can then use this Hook in multiple components like this:

import { useFetch } from './useFetch'; 
function MyComponent() { 
	const { data, loading, error } = useFetch(''); 
	if (loading) { 
		return <div>Loading...</div>; 
	if (error) { 
		return <div>{error.message}</div>; 
	return ( <div>{data}</div> ); 
  • You can use the useMemo Hook to optimize the performance of your components. The useMemo Hook allows you to memoize a value so that it is only recomputed if one of the dependencies has changed. This can be useful for optimizing the performance of your application if you have a component that is expensive to compute. Here's an example of how you can use the useMemo Hook:
import { useMemo } from 'react'; 
function MyComponent(props) { 
	const expensiveValue = useMemo(() => { 
		// Perform expensive computation here 
	}, 	[props.a, props.b]); 
	return ( <div>{expensiveValue}</div> ); 

In this example, the useMemo Hook is used to memoize the expensiveValue so that it is only recomputed if the props.a or props.b values change. This can help improve the performance of the component by avoiding unnecessary computations.