React Hooks and Modern Frontend Development

React Hooks revolutionized how we write React components. In this post, we’ll explore the most important hooks and modern React patterns.

What are React Hooks?

Hooks are functions that let you use state and other React features in functional components. They were introduced in React 16.8 to solve problems with class components.

Essential React Hooks

1. useState - Managing Component State

JSX
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>
  );
}
Click to expand and view more

2. useEffect - Side Effects

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

function UserProfile({ userId }) {
  const [user, setUser] = useState(null);

  useEffect(() => {
    // Fetch user data when userId changes
    fetch(`/api/users/${userId}`)
      .then(response => response.json())
      .then(data => setUser(data));

    // Cleanup function
    return () => {
      console.log('Cleanup');
    };
  }, [userId]); // Dependency array

  if (!user) return <div>Loading...</div>;

  return <div>{user.name}</div>;
}
Click to expand and view more

3. useContext - Context API

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

// Create context
const ThemeContext = createContext('light');

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

function Toolbar() {
  return <ThemeButton />;
}

function ThemeButton() {
  const theme = useContext(ThemeContext);
  return <button theme={theme}>Toggle Theme</button>;
}
Click to expand and view more

4. useReducer - Complex State Logic

JSX
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' })}>+</button>
      <button onClick={() => dispatch({ type: 'decrement' })}>-</button>
    </div>
  );
}
Click to expand and view more

Custom Hooks

Create reusable logic with custom hooks:

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

function useLocalStorage(key, initialValue) {
  const [storedValue, setStoredValue] = useState(() => {
    try {
      const item = window.localStorage.getItem(key);
      return item ? JSON.parse(item) : initialValue;
    } catch (error) {
      console.log(error);
      return initialValue;
    }
  });

  const setValue = (value) => {
    try {
      const valueToStore = value instanceof Function ? value(storedValue) : value;
      setStoredValue(valueToStore);
      window.localStorage.setItem(key, JSON.stringify(valueToStore));
    } catch (error) {
      console.log(error);
    }
  };

  return [storedValue, setValue];
}

// Usage
function App() {
  const [name, setName] = useLocalStorage('name', 'John');

  return (
    <input
      value={name}
      onChange={(e) => setName(e.target.value)}
    />
  );
}
Click to expand and view more

Modern React Patterns

1. Compound Components

JSX
import React from 'react';

function Tabs({ children }) {
  const [activeTab, setActiveTab] = React.useState(0);

  return React.Children.map(children, (child, index) =>
    React.cloneElement(child, {
      isActive: index === activeTab,
      onClick: () => setActiveTab(index)
    })
  );
}

function Tab({ isActive, onClick, children }) {
  return (
    <button
      className={isActive ? 'active' : ''}
      onClick={onClick}
    >
      {children}
    </button>
  );
}

// Usage
<Tabs>
  <Tab>Home</Tab>
  <Tab>About</Tab>
  <Tab>Contact</Tab>
</Tabs>
Click to expand and view more

2. Render Props

JSX
function MouseTracker({ render }) {
  const [position, setPosition] = useState({ x: 0, y: 0 });

  const handleMouseMove = (event) => {
    setPosition({
      x: event.clientX,
      y: event.clientY
    });
  };

  return (
    <div onMouseMove={handleMouseMove}>
      {render(position)}
    </div>
  );
}

// Usage
<MouseTracker
  render={({ x, y }) => (
    <p>The mouse position is ({x}, {y})</p>
  )}
/>
Click to expand and view more

React Hooks have made functional components more powerful and easier to work with, enabling better code reuse and cleaner component logic.

Copyright Notice

Author: Sanajit Jana

Link: https://sanajitjana.github.io/posts/react-hooks-and-modern-frontend-development/

License: CC BY-NC-SA 4.0

This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. Please attribute the source, use non-commercially, and maintain the same license.

Start searching

Enter keywords to search articles

↑↓
ESC
⌘K Shortcut