# Hooks in React

# Overview

Hooks allow you to use other React features without writing a class.

It provides function components to have access to state.

It also provides a way to write reusable and stateful logic.

# Why Hooks are useful in React

In previously, when we need to use state in any components we have to create a class based component.

Now, functional based components are stateful with Hooks and no need to create class based component.

# Some commonly used hooks in React.js are:

* `useState`: This hook allows you to add state to your functional components. It returns an array with two elements: the current state value and a function to update the state. We can use String, Number, Array or Object in useState.
    

```javascript
import React, { useState } from 'react';

function Counter() {
  // Declare a state variable called "count" and its setter function "setCount"
  const [count, setCount] = useState(0);

  // Event handler for incrementing the count
  const increment = () => {
    setCount(count + 1);
  };

  // Event handler for decrementing the count
  const decrement = () => {
    setCount(count - 1);
  };

  return (
    <div>
      <h2>Counter: {count}</h2>
      <button onClick={increment}>Increment</button>
      <button onClick={decrement}>Decrement</button>
    </div>
  );
}

export default Counter;
```

* `useEffect`: This hook is used to perform side effects in your components, such as fetching data, subscribing to events, or manipulating the DOM. It runs after every render and can be used to handle component lifecycle events. It will run on mount and update.
    

```javascript
import React, { useState, useEffect } from 'react';

function UseEffectComponent() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    setTimeout(() => {
      setCount((count) => count + 1);
    }, 1000);
  }, []);
  
  return <h1>I've rendered {count} times!</h1>;
}

export default UseEffectComponent;
```

* `useContext`: This hook allows you to access the value of a React context within a functional component. It takes a context object created by `React.createContext` and returns the current context value.
    

```javascript
import { useState, createContext, useContext } from "react";
const UserContext = createContext();

function Func1() {
  const [user, setUser] = useState("Jesse Hall");

  return (
    <UserContext.Provider value={user}>
      <h1>{`Hello ${user}!`}</h1>
      <Func2 />
      </UserContext.Provider>
    );
}

function Func2() {
  return (
    <>
      <h1>Component 2</h1>
      <Func3 />
    </>
  );
}

function Func3() {
    const user = useContext(UserContext);
    return (
        <>
          <h1>Component 3</h1>
          <h2>{`Hello ${user} again!`}</h2>
        </>
      );
}

export default Func1;
```

* `useReducer`: This hook is an alternative to `useState` and is used for managing more complex state logic. It returns the current state and a dispatch function to update the state, similar to how a reducer works in Redux.
    

```javascript
import React, { useReducer } from 'react';

// Reducer function
const reducer = (state, action) => {
  switch (action.type) {
    case 'INCREMENT':
      return { count: state.count + 1 };
    case 'DECREMENT':
      return { count: state.count - 1 };
    default:
      return state;
  }
};

// Component using useReducer
function Counter() {
  const initialState = { count: 0 };
  const [state, dispatch] = useReducer(reducer, initialState);

  const increment = () => {
    dispatch({ type: 'INCREMENT' });
  };

  const decrement = () => {
    dispatch({ type: 'DECREMENT' });
  };

  return (
    <div>
      <h2>Count: {state.count}</h2>
      <button onClick={increment}>Increment</button>
      <button onClick={decrement}>Decrement</button>
    </div>
  );
}

export default Counter;
```

* `useCallback` and `useMemo`: These hooks are used for performance optimization. `useCallback` memoizes a function, preventing unnecessary re-renders, while `useMemo` memoizes a value, preventing unnecessary re-computations.
    

```javascript
import React, { useState, useCallback } from 'react';

function ExampleComponent() {
  const [count, setCount] = useState(0);

  // Define a callback function using useCallback
  const handleClick = useCallback(() => {
    setCount(count + 1);
  }, [count]);

  return (
    <div>
      <h2>Count: {count}</h2>
      <button onClick={handleClick}>Increment</button>
    </div>
  );
}

export default ExampleComponent;
```

* `useRef`: The `useRef` hook in React allows you to create a mutable reference that persists across re-renders of a component. It can be used to access and modify DOM elements, store mutable values, or preserve values between renders without triggering a re-render.
    

```javascript
import { useRef } from "react";

const RefComponent = () => {
  const inputRef = useRef(null);

  const handleClick = () => {
    // Modifying the input element using the ref
    inputRef.current.value = "New value";
    
    // Focusing on the input element using the ref
    inputRef.current.focus();
  };

  return (
    <div>
      <input type="text" ref={inputRef} />
      <button onClick={handleClick}>Click</button>
    </div>
  );
};

export default RefComponent;
```
