🚀 React Interview Experience (August 2025): Airtel (Part- 2)
Overview
This document outlines a React developer interview experience from August 2025. The interview covered various aspects of front-end development, including React, JavaScript, and general problem-solving skills. The candidate was evaluated on their ability to implement common UI features, handle asynchronous operations, and optimize application performance.
Interview Rounds
The interview process included questions testing the candidate's understanding of React concepts and their practical application.
Question 1: Traffic Light Implementation
The candidate was asked to build a traffic light component using React, with lights switching colors (green, yellow, red) at predetermined intervals and looping indefinitely. The solution involved using useState to manage the current light and useEffect with setInterval to control the timing. CSS was used for styling.
const TrafficLight = () => {
const [light, setLight] = useState("green");
useEffect(() => {
const interval = setInterval(
() => {
switch (light) {
case "green":
setLight("yellow");
break;
case "yellow":
setLight("red");
break;
case "red":
setLight("green");
break;
default:
break;
}
},
light === "green" ? 3000 : light === "yellow" ? 500 : 4000
);
return () => clearInterval(interval);
}, [light]);
const getLightStyle = (color) => ({
backgroundColor: light === color ? color : "gray",
height: "100px",
width: "100px",
borderRadius: "50%",
margin: "10px",
});
return (
<div
style={{ display: "flex", flexDirection: "column", alignItems: "center" }}
>
<div style={getLightStyle("red")} />
<div style={getLightStyle("yellow")} />
<div style={getLightStyle("green")} />
</div>
);
};
export default function App() {
return (
<div className="App">
<TrafficLight />
</div>
);
}
Question 2: Handling Asynchronous API Calls
The candidate was presented with a scenario involving two APIs and was asked how to submit data only after both APIs returned successful responses. The answer explored using Promise.all for independent API calls, sequential await for dependent calls, and Promise.allSettled for handling partial failures. Code examples were provided for each approach.
// Using Promise.all
async function submitData() {
try {
const [res1, res2] = await Promise.all([
fetch("/api/endpoint1").then(r => r.json()),
fetch("/api/endpoint2").then(r => r.json())
]);
console.log("Both API calls succeeded:", res1, res2);
// now trigger submit
await fetch("/api/submit", {
method: "POST",
body: JSON.stringify({ data1: res1, data2: res2 })
});
console.log("Final submit successful");
} catch (error) {
console.error("One of the APIs failed:", error);
}
}
// Using Sequential Calls (If second depends on first)
async function submitData() {
try {
const res1 = await fetch("/api/endpoint1").then(r => r.json());
const res2 = await fetch("/api/endpoint2", {
method: "POST",
body: JSON.stringify({ id: res1.id }) // using res1 data
}).then(r => r.json());
// now final submit
await fetch("/api/submit", {
method: "POST",
body: JSON.stringify({ res1, res2 })
});
console.log("Final submit successful");
} catch (error) {
console.error("Error:", error);
}
}
// Using Promise.allSettled
const results = await Promise.allSettled([apiCall1(), apiCall2()]);
const success = results.every(r => r.status === "fulfilled");
if (success) {
await submit();
} else {
console.error("One of the APIs failed:", results);
}
Question 3: Application Health Check
The candidate was asked how to determine if an application is working correctly from a single page. The answer included checking API calls in the network tab, verifying UI rendering, inspecting console errors, using a health check API (if available), performing manual smoke tests, and employing automated E2E testing.
Question 4: Generics
The candidate was questioned on generics. The answer covered the concept of generics allowing code to work with any type while maintaining type safety, using type parameters, and providing a TypeScript example.
function identity<T>(arg: T): T {
return arg;
}
let str = identity<string>("Hello"); // str: string
let num = identity(42); // num: number (inferred automatically)
Question 5: PR Reviews
The candidate was asked about their approach to pull request reviews. The response included understanding the context, checking code quality and standards, verifying correctness and logic, considering performance, assessing security and API handling, ensuring tests, providing constructive feedback, and collaborating with the team.
Question 6: Hot Module Replacement (HMR)
The candidate was asked about Hot Module Replacement (HMR). The answer defined HMR as a feature that allows modules to be updated in a running application without a full page reload, preserving application state. It described how HMR works and its benefits in React development.
Question 7: Tree Shaking
The candidate was asked about Tree Shaking. The response defined Tree Shaking as a bundler optimization that removes unused code from the final JavaScript bundle, reducing bundle size and improving application performance.
Question 8: Redux Thunk vs. Promises
The candidate was asked why Redux Thunk is used instead of Promises directly. The answer explained that Redux only handles synchronous actions by default and that Redux Thunk allows action creators to return functions for handling asynchronous logic and dispatching multiple actions. The response highlighted the advantages of Thunk over raw promises, including control over dispatching multiple actions, handling complex async logic, and maintaining pure reducers.
Question 9: Infinite Scrolling Implementation
The candidate was asked how to implement infinite scrolling in a React app. The answer described two common approaches: using a scroll event listener and using IntersectionObserver. Code examples were provided for both methods.
// Using scroll event listener
import { useEffect, useState } from "react";
const InfiniteScrollList = () => {
const [items, setItems] = useState<any[]>([]);
const [page, setPage] = useState(1);
const [loading, setLoading] = useState(false);
// Fetch data
const fetchData = async () => {
setLoading(true);
const res = await fetch(`https://jsonplaceholder.typicode.com/posts?_page=${page}&_limit=10`);
const data = await res.json();
setItems(prev => [...prev, ...data]);
setLoading(false);
};
useEffect(() => {
fetchData();
}, [page]);
// Scroll event
useEffect(() => {
const handleScroll = () => {
if (
window.innerHeight + document.documentElement.scrollTop + 1 >=
document.documentElement.scrollHeight
) {
setPage(prev => prev + 1);
}
};
window.addEventListener("scroll", handleScroll);
return () => window.removeEventListener("scroll", handleScroll);
}, []);
return (
<div>
<h2>Infinite Scroll Demo</h2>
{items.map((item, i) => (
<p key={i}>{item.title}</p>
))}
{loading && <p>Loading...</p>}
</div>
);
};
export default InfiniteScrollList;
// Using IntersectionObserver
import { useEffect, useRef, useState } from "react";
const InfiniteScrollObserver = () => {
const [items, setItems] = useState<any[]>([]);
const [page, setPage] = useState(1);
const [loading, setLoading] = useState(false);
const loaderRef = useRef<HTMLDivElement | null>(null);
const fetchData = async () => {
setLoading(true);
const res = await fetch(`https://jsonplaceholder.typicode.com/posts?_page=${page}&_limit=10`);
const data = await res.json();
setItems(prev => [...prev, ...data]);
setLoading(false);
};
useEffect(() => {
fetchData();
}, [page]);
useEffect(() => {
const observer = new IntersectionObserver(entries => {
if (entries[0].isIntersecting) {
setPage(prev => prev + 1);
}
});
if (loaderRef.current) {
observer.observe(loaderRef.current);
}
return () => {
if (loaderRef.current) observer.unobserve(loaderRef.current);
};
}, []);
return (
<div>
<h2>Infinite Scroll with Observer</h2>
{items.map((item, i) => (
<p key={i}>{item.title}</p>
))}
<div ref={loaderRef}>{loading && <p>Loading...</p>}</div>
</div>
);
};
export default InfiniteScrollObserver;
Question 10: Preventing Memory Leaks
The candidate was asked about preventing memory leaks in a React component. The answer covered common causes of memory leaks (unsubscribed event listeners, uncleared timers, unsubscribed API calls, and state updates on unmounted components) and solutions like cleaning up in useEffect, clearing timers/intervals, canceling API calls, cleaning WebSocket/subscriptions, and lazy loading & proper unmounting.
Key Takeaways
This interview experience highlights the importance of a strong understanding of React fundamentals, asynchronous JavaScript, and front-end optimization techniques. The candidate demonstrated knowledge of common UI implementations, API handling strategies, and methods for preventing memory leaks. These insights can help other developers better prepare for similar React developer roles.
Original Source
This experience was originally published on medium. Support the author by visiting the original post.
Read on medium