React Hooks Explained

React Hooks Explained

React Hooks Explained

React Hooks were introduced in React 16.8 as a way to use state and other React features without writing a class component. They allow you to "hook into" React state and lifecycle features from function components.

Why Hooks?

Before Hooks, if you needed state or lifecycle methods in your component, you had to use a class component. This led to complex components that were difficult to understand and reuse. Hooks solve this problem by allowing you to use state and other React features in functional components.

Common Hooks

useState

The useState hook allows you to add state to functional components. It returns a stateful value and a function to update it.

import { useState } from 'react';

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

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

useEffect

The useEffect hook allows you to perform side effects in functional components. It's similar to lifecycle methods like componentDidMount, componentDidUpdate, and componentWillUnmount combined.

import { useState, useEffect } from 'react';

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

  useEffect(() => {
    document.title = `You clicked ${count} times`;
    
    // Cleanup function (equivalent to componentWillUnmount)
    return () => {
      document.title = 'React App';
    };
  }, [count]); // Only re-run if count changes

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

Custom Hooks

One of the most powerful features of Hooks is the ability to create your own custom hooks. This allows you to extract component logic into reusable functions.

import { useState, useEffect } from 'react';

function useWindowWidth() {
  const [width, setWidth] = useState(window.innerWidth);
  
  useEffect(() => {
    const handleResize = () => setWidth(window.innerWidth);
    window.addEventListener('resize', handleResize);
    return () => window.removeEventListener('resize', handleResize);
  }, []);
  
  return width;
}

function MyComponent() {
  const width = useWindowWidth();
  return <div>Window width: {width}</div>;
}

Rules of Hooks

There are two important rules to follow when using Hooks:

  1. Only call Hooks at the top level of your function component or custom Hook.
  2. Don't call Hooks inside loops, conditions, or nested functions.

Following these rules ensures that Hooks are called in the same order each time a component renders, which is important for React to correctly preserve the state of Hooks between multiple useState and useEffect calls.

Conclusion

React Hooks provide a more direct API to the React concepts you already know: props, state, context, refs, and lifecycle. They allow you to reuse stateful logic without changing your component hierarchy, making your code more readable and maintainable.

By understanding and using Hooks effectively, you can write cleaner, more concise React components that are easier to understand and test.