During my recent job search, I encountered this question multiple times, posed by interviewers from reputable companies such as FlexCar and BetterHalf. It underscores the importance of understanding custom hooks, state management and component composition in React interviews.
we’ll walk through the process of building a counter that not only displays the current count but also provides the functionality to start, pause, and reset it. We’ll focus on modularity and encapsulation, breaking down our components into smaller, reusable parts. By the end of this tutorial, you’ll have a deeper understanding of structuring components and hooks for enhanced maintainability and flexibility.
To achieve modularity, we’ll break down our Counter component into smaller, reusable parts. Let’s start with the custom hook responsible for managing the counter state and actions.
// Custom hook for managing counter state and actions
import { useState, useEffect } from 'react';
const useCounterHook = () => {
// State variables for count and running state
const [count, setCount] = useState(0);
const [isRunning, setIsRunning] = useState(false);
// Functions to handle start, pause, and reset actions
const handleStart = () => {
setIsRunning(true);
};
const handlePause = () => {
setIsRunning(false);
};
const handleReset = () => {
setCount(0);
setIsRunning(false);
};
// Effect for updating count based on running state
useEffect(() => {
let intervalId;
if (isRunning) {
intervalId = setInterval(() => {
setCount(prevCount => prevCount + 1);
}, 1000);
} else {
clearInterval(intervalId);
}
return () => clearInterval(intervalId);
}, [isRunning]);
// Return state variables and action functions
return { count, handleStart, handlePause, handleReset };
};
export default useCounterHook;
In the above custom hook, we have exposed the count and method to start, pause and reset the count. We will use these exposed values in the main component as below.
import React, { useState } from "react";
import "./styles.css";
import useCounterHook from "./useCounterHook";
const App = () => {
const { count, handleStart, handlePause, handleReset } = useCounterHook();
return (
<div className="counter">
<div className="counter">{count}</div>
<button onClick={handleStart}>Play</button>
<button onClick={handlePause}>Pause</button>
<button onClick={handleReset}>Reset</button>
</div>
);
};
export default App;
- We use the useState hook to maintain the count state and a boolean flag (isRunning) to track whether the counter is running or paused. Here, we can use “useRef” for storing the ‘isRunning’ flag to avoid unnecessary re-renders.
- The handleStart, handlePause and handleReset functions update the state based on user interactions.
- Inside the useEffect hook, we set up an interval to increment the count every second when the counter is running. We clear the interval when the counter is paused or reset.
This is how the components work with start, pause and reset functionality.
1 comment
[…] Question 3: Create a custom hook that provides a counter that can be used to display on the screen and three buttons play, pause, and reset with functionality in react (Link to the article) […]