# The Basics of React Hooks: A Comprehensive Guide - Part 1

React Hooks, introduced in React 16.8, have changed the way we write functional components in React applications. They allow us to use state and other React features without writing a class. This blog aims to demonstrate the most commonly used hooks: `useState`, `useEffect`, and `useRef`, providing a foundation for building react applications.

### **The**`useState` Hook

Why Use State Instead of Normal javascript variable let or const

1. **Reactivity:** State variables are reactive. When state changes, React re-renders the component to reflect those changes. Normal variables don’t trigger re-renders.
    
2. **Persistence:** State persists between re-renders, while normal variables get reset.
    
3. **Consistency:** React ensures state consistency across re-renders, providing a reliable and predictable way to manage dynamic data.
    
    ```javascript
    import React, { useState } from 'react';
    
    function ExampleComponent() {
      // Normal state update pattern
      const [countNormal, setCountNormal] = useState(0);
    
      // prevState-based state update pattern
      const [countPrevState, setCountPrevState] = useState(0);
    
      // Normal state update when clicking the "Click me (Normal)" button
      const handleNormalClick = () => {
        // Increment count by 1
        setCountNormal(countNormal + 1);
      };
    
      // prevState-based state update when clicking the "Click me (prevState)" button
      const handlePrevStateClick = () => {
        // Increment count by 1 based on previous state
        setCountPrevState((prevState) => prevState + 1);
      };
    
      return (
        <div>
          <div>
            <p>You clicked {countNormal} times (Normal)</p>
            <button onClick={handleNormalClick}>
              Click me (Normal)
            </button>
          </div>
          <div>
            <p>You clicked {countPrevState} times (prevState)</p>
            <button onClick={handlePrevStateClick}>
              Click me (prevState)
            </button>
          </div>
        </div>
      );
    }
    
    export default ExampleComponent;
    ```
    
    When you need to update a state based on its previous value, using `(prevState) => ...` is essential. This pattern ensures that your updates are dynamic and reflect the latest state, even in asynchronous or concurrent situations.  
    When you want to increment or decrement a value based on its current state, like `setCount((prevState) => prevState + 1)` or `setCount((prevState) => prevState - 1)`
    
    **The**`useEffect` Hook
    
    `useEffect` is a built-in hook in React that allows you to perform side effects in function components. Side effects are operations that happen after or as a result of the main logic of your component, such as data fetching, DOM manipulation, or setting up subscriptions.  
    It serves as a replacement for lifecycle methods like `componentDidMount`, `componentDidUpdate`, and `componentWillUnmount` in class components.
    
    1. When you don't provide a dependency array, the effect runs after every render. This is similar to `componentDidUpdate` in class components and is used for side effects that should run after each render.
        
    2. When you pass an empty dependency array, the effect runs only once after the initial render. This is equivalent to `componentDidMount` in class components and is used for one-time setup or data fetching.
        
    3. When you pass specific dependencies to `useEffect`, the effect will run whenever any of those dependencies change. This is useful for controlling when the effect should execute based on specific data changes
        
    
    ```javascript
    import React, { useState, useEffect } from 'react';
    
    function ExampleComponent({ data }) {
      const [count, setCount] = useState(0);
    
      // Effect with specific dependencies
      useEffect(() => {
        // This code runs when 'data' changes
        console.log('Data changed:', data);
      }, [data]);
    
      // Effect with empty dependency array (runs once)
      useEffect(() => {
        console.log('Component mounted (initial render)');
        return () => {
          console.log('Component unmounted');
        };
      }, []);
    
      // Effect without a dependency array (runs after every render)
      useEffect(() => {
        console.log('Component re-rendered');
      });
    
      return (
        <div>
          <p>You clicked {count} times</p>
          <button onClick={() => setCount(count + 1)}>Click me</button>
        </div>
      );
    }
    ```
    
    The `return` statement in `useEffect` is used to define a cleanup function that runs when the component unmounts or when the state value changes. This cleanup function is essential for tasks like clearing intervals, unsubscribing from subscriptions, or releasing resources to prevent memory leaks.
    
    ```javascript
    import React, { useState, useEffect } from 'react';
    
    function TimerComponent() {
      const [timer, setTimer] = useState(0);
    
      useEffect(() => {
        const intervalId = setInterval(() => {
          setTimer((prevTimer) => prevTimer + 1);
        }, 1000);
    
        // Cleanup function to clear the interval
        return () => {
          clearInterval(intervalId);
        };
      }, []);
    
      return <div>Timer: {timer} seconds</div>;
    }
    ```
    
    In this example, the `return` statement is used to clear the interval created by `setInterval` when the component unmounts. This ensures that there are no lingering intervals that could cause memory leaks
    
    ### **The**`useRef` Hook
    
    `useRef` hook in React allows you to create and manage references to DOM elements or to persist values across renders without causing re-renders. You can directly access the dom element.
    
    Use `useRef` when you need to directly manipulate DOM elements, such as focusing on an input field, measuring dimensions, or animating elements.
    
    Don't use `useRef` for managing component state that affect rendering.
    

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

function MyComponent() {
  const inputRef = useRef();

  useEffect(() => {
    // Focus the input element when the component mounts
    inputRef.current.focus();
  }, []);

  return <input ref={inputRef} />;
}
```

In the next article, we will focus on more optimization hooks like useMemo, and useCallback React provides to us.
