#11 React Hooks

React Hooks were introduced in React 16.8 and have revolutionized the way we write React components. They allow you to use state and other React features in functional components, making them more powerful and easier to manage. In this article, we will cover the basics of hooks, including useState and useEffect, creating custom hooks, and exploring advanced hooks like useContext and useReducer.

Introduction to Hooks

Hooks are functions that let you “hook into” React state and lifecycle features from functional components. They enable you to use state and other React features without writing a class. The two most commonly used hooks are useState and useEffect.

useState and useEffect

useState

The useState hook lets you add state to functional components. It returns an array with two elements: the current state value and a function to update it.

Example:

import React, { 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>
  );
}

export default Counter;

In this example, useState(0) initializes the state with a value of 0. The count variable holds the current state value, and setCount is the function to update it.

useEffect

The useEffect hook lets you perform side effects in functional components. It’s similar to componentDidMount, componentDidUpdate, and componentWillUnmount lifecycle methods combined in class components.

Example:

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

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

  useEffect(() => {
    document.title = `You clicked ${count} times`;

    // Cleanup function
    return () => {
      document.title = 'React App';
    };
  }, [count]);

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

export default Counter;

In this example, useEffect updates the document title whenever the count state changes. The optional cleanup function resets the title when the component unmounts or before the effect re-runs.

Custom Hooks

Custom hooks allow you to extract and reuse logic across multiple components. A custom hook is a JavaScript function that starts with “use” and can call other hooks.

Example:

import { useState, useEffect } from 'react';

function useFetch(url) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    fetch(url)
      .then(response => response.json())
      .then(data => {
        setData(data);
        setLoading(false);
      });
  }, [url]);

  return { data, loading };
}

export default useFetch;

In this example, useFetch is a custom hook that fetches data from a given URL. It manages the data and loading state and can be reused in any component.

Usage:

import React from 'react';
import useFetch from './useFetch';

function App() {
  const { data, loading } = useFetch('https://api.example.com/data');

  if (loading) {
    return <p>Loading...</p>;
  }

  return (
    <div>
      <pre>{JSON.stringify(data, null, 2)}</pre>
    </div>
  );
}

export default App;

useContext, useReducer, and Other Advanced Hooks

useContext

The useContext hook lets you access context values in functional components. It is used to avoid prop drilling and share state across the component tree.

Example:

import React, { useContext } from 'react';

const ThemeContext = React.createContext('light');

function ThemedComponent() {
  const theme = useContext(ThemeContext);

  return (
    <div style={{ background: theme = = = 'light' ? '#fff' : '#333', color: theme = = = 'light' ? '#000' : '#fff' }}>
      The current theme is {theme}
    </div>
  );
}

function App() {
  return (
    <ThemeContext.Provider value="dark">
      <ThemedComponent />
    </ThemeContext.Provider>
  );
}

export default App;

In this example, useContext(ThemeContext) retrieves the current value of ThemeContext.

useReducer

The useReducer hook is an alternative to useState for managing complex state logic. It is similar to Redux but simpler to use within React components.

Example:

import React, { useReducer } from 'react';

const initialState = { count: 0 };

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, initialState);

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

export default Counter;

In this example, useReducer manages the count state with a reducer function and dispatch method.

Conclusion

React Hooks provide a powerful and flexible way to manage state and side effects in functional components. By mastering hooks like useState, useEffect, custom hooks, useContext, and useReducer, you can write cleaner and more efficient React code.

Stay tuned for more in-depth React tutorials!


Tags

#React #JavaScript #FrontendDevelopment #WebDevelopment #ReactHooks #useState #useEffect #CustomHooks #useContext #useReducer #FunctionalComponents #ReactTutorial #Programming #Coding #SoftwareDevelopment #UIDevelopment

Leave a Reply