400===Dev Library/React

What are React Hooks?

블로글러 2024. 6. 23. 16:13

Introduction

React hooks revolutionized the way developers write React components. Introduced in React 16.8, hooks allow functional components to use state and other React features without writing a class. This guide will walk you through the core concepts of React hooks, provide detailed examples, and offer practical insights for their effective use.

The Big Picture

Imagine you're constructing a building. Traditional React components are like pre-fabricated rooms – they come with everything built-in, but they're rigid and hard to customize. React hooks are like modular building blocks – they allow you to add exactly the features you need, precisely where you need them, making your code more flexible and easier to maintain.

Core Hooks

1. useState: Managing State

The useState hook allows functional components to manage state.

Example:

import React, { useState } from 'react';

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

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

Key Points:

  • useState returns an array with two elements: the current state value and a function to update it.
  • The argument to useState is the initial state value.

2. useEffect: Handling Side Effects

useEffect allows you to perform side effects in functional components, such as data fetching, subscriptions, or manually changing the DOM.

Example:

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

function DataFetcher() {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetch('https://api.example.com/data')
      .then(response => response.json())
      .then(result => setData(result));
  }, []); // Empty dependency array means this effect runs once on mount

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

Key Points:

  • The effect runs after every render by default.
  • The second argument (dependency array) controls when the effect runs.
  • Return a function from useEffect for cleanup operations.

3. useContext: Consuming Context

useContext provides a way to pass data through the component tree without manually passing props.

Example:

import React, { createContext, useContext } from 'react';

const ThemeContext = createContext('light');

function ThemedButton() {
  const theme = useContext(ThemeContext);
  return <button style={{ background: theme }}>I'm styled by theme context!</button>;
}

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

Key Points:

  • useContext accepts a context object and returns the current context value.
  • The component re-renders when the context value changes.

4. useReducer: Complex State Logic

useReducer is preferable to useState when you have complex state logic involving multiple sub-values or when the next state depends on the previous one.

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>
      Count: {state.count}
      <button onClick={() => dispatch({ type: 'increment' })}>+</button>
      <button onClick={() => dispatch({ type: 'decrement' })}>-</button>
    </div>
  );
}

Key Points:

  • useReducer returns the current state and a dispatch function.
  • It's useful for managing state objects with multiple sub-fields.

Advanced Hooks

5. useRef: Accessing DOM Elements

useRef returns a mutable ref object whose .current property is initialized to the passed argument. It's commonly used to access DOM elements directly.

Example:

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

function AutoFocusInput() {
  const inputRef = useRef(null);

  useEffect(() => {
    inputRef.current.focus();
  }, []);

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

Key Points:

  • useRef doesn't cause re-renders when its content changes.
  • It's useful for storing any mutable value, not just DOM refs.

6. useMemo and useCallback: Performance Optimization

These hooks help in optimizing performance by memoizing expensive computations and callback functions.

Example:

import React, { useMemo, useCallback, useState } from 'react';

function ExpensiveComponent({ data, onItemClick }) {
  const sortedData = useMemo(() => {
    return data.sort((a, b) => a.value - b.value);
  }, [data]);

  const handleClick = useCallback((item) => {
    console.log('Item clicked:', item);
    onItemClick(item);
  }, [onItemClick]);

  return (
    <ul>
      {sortedData.map(item => (
        <li key={item.id} onClick={() => handleClick(item)}>{item.value}</li>
      ))}
    </ul>
  );
}

Key Points:

  • useMemo memoizes the result of a computation.
  • useCallback memoizes a callback function.
  • Both help prevent unnecessary re-renders in child components.

Best Practices and Tips

  1. Don't overuse hooks: Start with simpler solutions and use hooks when you need them.
  2. Follow the Rules of Hooks: Only call hooks at the top level and from React functions.
  3. Custom Hooks: Extract reusable logic into custom hooks for better code organization.
  4. Dependency Arrays: Be careful with dependency arrays in useEffect, useMemo, and useCallback.
  5. Performance: Use the React DevTools Profiler to identify and solve performance issues.

Conclusion

React hooks provide a powerful and flexible way to use state and other React features in functional components. By mastering hooks, you can write more concise, reusable, and easier-to-understand React code. As you continue to work with hooks, you'll discover even more ways to leverage their power in your React applications.

Remember, the key to becoming proficient with hooks is practice. Start incorporating them into your projects, and you'll soon see the benefits they bring to your React development workflow.

Further Resources

Happy coding with React hooks!

728x90