# 12-13 : React Hooks

# **Introduction to Hooks in React:**

1. **Definition**:
    
    * Hooks are functions that allow functional components to access React state and lifecycle features.
        
    * They were introduced in React 16.8 to address the limitations of class components and promote the use of functional components.
        
2. **Motivation**:
    
    * Simplify and streamline state management and side effects in functional components.
        
    * Reduce the complexity of component logic and improve code readability.
        
    * Encourage the reuse of logic across components.
        
3. **Built-in Hooks**:
    
    * React provides several built-in hooks that cover common use cases:
        
        * `useState`: Allows functional components to manage local state.
            
        * `useEffect`: Enables side effects like data fetching, subscriptions, or DOM manipulation.
            
        * `useContext`: Provides access to the nearest context.
            
        * `useReducer`: Alternative to `useState` for managing complex state logic.
            
        * `useCallback`, `useMemo`: Memoize functions and values to optimize performance.
            
        * `useRef`: Access and interact with DOM elements or store mutable values.
            
        * `useLayoutEffect`: Similar to `useEffect`, but fires synchronously after all DOM mutations.
            

## **1\. useState Hook**:

* Allows functional components to manage local state.
    

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

function Counter() {
  // Declare a state variable named "count" initialized to 0
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>Count: {count}</p>
      {/* Event handler to increment count */}
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

export default Counter;
```

## **2.useEffect Hook**:

* Enables side effects like data fetching, subscriptions, or DOM manipulation.
    

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

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

  // useEffect hook to perform side effects
  useEffect(() => {
    // Update the document title after every render
    document.title = `You clicked ${count} times`;
  });

  return (
    <div>
      <p>Count: {count}</p>
      {/* Event handler to increment count */}
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

export default Example;
```

# 3.useEffect Hook with All Possibilities:

## **1\. Basic Usage: 🚨💀**

**Description:** The simplest form of `useEffect` takes a callback function and runs it after every render.

```javascript
useEffect(() => {
  console.log('Component rendered - This effect runs after every render');
});
```

### **🚨💀 Side Effects Without Dependencies: 💀🚨**

* **Description:** If you <mark>don't provide a dependency array</mark>, the effect runs after <mark>every render,</mark> which may lead to 🐌 **performance** issues if not used carefully.
    

## **2\. Usage with Dependency Array:**

**Description:**`useEffect` can take a dependency array as the second argument. This array contains variables that, when changed, trigger the effect to re-run.

```javascript
useEffect(() => {
  console.log('Counter value changed:', counter);
}, [counter]);
```

## **3\. Usage with Empty Dependency Array:**

**Description:** Providing an empty dependency array ensures that the effect runs <mark>only once </mark> after the initial render.

```javascript
useEffect(() => {
  console.log('Component mounted : Only once after Initial Render');
}, []); // Empty dependency array ensures the effect runs only once after mount
```

## **4\. Cleanup Function:**

**Description:**`useEffect` can return a cleanup function to perform any necessary cleanup when the component unmounts.

```javascript
useEffect(() => {
  console.log('Components Mounted');
  const subscription = subscribeToData();

  // Cleanup function
  return () => {
    console.log('Components Unmounted.');
    subscription.unsubscribe();
  };
}, []); // Empty dependency array ensures the effect runs only once after mount
```

## **5\. Combining Multiple useEffect Calls:**

**Description:** You can use multiple `useEffect` calls in a single component to separate concerns and manage side effects independently.

```javascript
useEffect(() => {
  console.log('Effect 1');
}, [value1]);

useEffect(() => {
  console.log('Effect 2');
}, [value2]);
```

## **6\. Conditionally Running Effects:**

**Description:** You can conditionally run effects by placing the condition inside the effect itself.

```javascript
useEffect(() => {
  if (condition) {
    console.log('Effect runs when condition is true');
  }
}, [condition]);
```

## **7\. Using useEffect for Document Title Updates:**

**Description:**`useEffect` can be used to dynamically update the document title based on component state.

```javascript
useEffect(() => {
  document.title = `Count: ${count}`;
}, [count]);
```
