Published on

8 - React Hooks with TypeScript: Practical Examples with Comments to Master Key Hooks

Authors
  • avatar
    Name
    Jonas de Oliveira
    Twitter

In the React ecosystem, hooks have revolutionized how we build functional components by offering a simple and elegant way to manage state, side effects, context, and more—without the need for classes. Integrating these hooks with TypeScript further enhances code robustness and safety by providing static typing and improved developer experience. Below are practical examples of the most commonly used React hooks with TypeScript, complete with detailed comments to explain each step.

1. useState

The useState hook allows you to add local state to functional components. In the example below, we create a counter typed as a number.

import React, { useState } from 'react';

const Counter: React.FC = () => {
  // Initialize the 'count' state with a value of 0 and ensure it is of type number.
  const [count, setCount] = useState<number>(0);

  return (
    <div>
      {/* Display the current counter value */}
      <p>Counter: {count}</p>
      {/* When clicked, update the state by incrementing the previous value */}
      <button onClick={() => setCount(prev => prev + 1)}>Increment</button>
    </div>
  );
};

export default Counter;

2. useEffect

The useEffect hook manages side effects, such as API calls or timer manipulation. In the example below, we simulate fetching data with a delay and update the state accordingly.

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

const DataFetcher: React.FC = () => {
  // State to store the fetched data (an array of strings)
  const [data, setData] = useState<string[]>([]);
  // State to manage the loading indicator
  const [loading, setLoading] = useState<boolean>(true);

  // useEffect with an empty dependency array to run only once when the component mounts
  useEffect(() => {
    // Asynchronous function to simulate data fetching
    const fetchData = async () => {
      // Simulate an API call with a 1.5-second delay
      const result = await new Promise<string[]>(resolve =>
        setTimeout(() => resolve(['Item 1', 'Item 2', 'Item 3']), 1500)
      );
      // Update the state with the fetched data
      setData(result);
      // Set loading to false after the data is loaded
      setLoading(false);
    };

    fetchData();
  }, []); // Runs only once after the component mounts

  // Display a loading message while data is being fetched
  if (loading) return <p>Loading data...</p>;

  return (
    <div>
      <h3>Data:</h3>
      <ul>
        {/* Render each item in the data array */}
        {data.map((item, index) => (
          <li key={index}>{item}</li>
        ))}
      </ul>
    </div>
  );
};

export default DataFetcher;

Final Thoughts

Mastering React hooks with TypeScript is essential for developing modern, scalable, and high-quality applications. Each hook addresses a specific need—from state management and side effects to performance optimizations and DOM interactions. The examples above, complete with detailed comments, demonstrate how to use these hooks safely and effectively, showcasing best practices that are highly valued in the job market.