Intermediate Level React Interview Questions & Answers – Set 2
Q1. When would you extract logic into a custom hook?
- When logic is reused across multiple components.
- Keeps components cleaner and promotes code reuse.
Q2. How do you build a custom hook for fetching API data?
function useFetch(url) {
const [data, setData] = useState(null);
useEffect(() => {
fetch(url)
.then(res => res.json())
.then(setData);
}, [url]);
return data;
}
Q3. What is the difference between a custom hook and a higher-order component (HOC)?
| Feature | Custom Hook | HOC |
|---|---|---|
| Definition | Function that uses React hooks | Wrapper component |
| Complexity | Simple, functional | Can become nested |
| Reusability | High | High, but less readable |
Q4. How do you build a custom hook for form validation?
- Store form values and errors inside the hook.
- Return change handlers and validation helpers.
function useFormValidation(initialValues, validate) {
const [values, setValues] = useState(initialValues);
const [errors, setErrors] = useState({});
const handleChange = (e) => {
const { name, value } = e.target;
setValues({ ...values, [name]: value });
setErrors(validate(values));
};
return { values, errors, handleChange };
}
Q5. How do you create a reusable hook for debouncing user input?
function useDebounce(value, delay) {
const [debounced, setDebounced] = useState(value);
useEffect(() => {
const handler = setTimeout(() => setDebounced(value), delay);
return () => clearTimeout(handler);
}, [value, delay]);
return debounced;
}
Q6. What is prop drilling, and why is it a problem?
- Passing props through many nested components.
- Makes the code harder to maintain.
<Parent>
<Child>
<GrandChild data={value} />
</Child>
</Parent>
Q7. How does the Context API solve prop drilling?
- Context lets you share data globally without passing props manually.
const ThemeContext = React.createContext();
function App() {
return (
<ThemeContext.Provider value="dark">
<Child />
</ThemeContext.Provider>
);
}
function Child() {
const theme = useContext(ThemeContext);
return <div>{theme}</div>;
}Q8. When should you prefer Redux over Context API?
- App is large or state is complex.
- Many components depend on shared data.
- You need middleware (e.g., async logic, logging).
- Context can cause re-renders in many components when values change.
Q9. What is Redux Toolkit, and why is it preferred?
- Official, simplified Redux library.
- Features:
createSlice()→ concise reducersconfigureStore()→ preconfigured store- Built-in async & immutability handling
Q10. How do you implement middleware in Redux?
Middleware = logic between dispatch and reducer.
Example: redux-thunk for async calls.
const fetchData = () => (dispatch) => {
fetch("/api")
.then(res => res.json())
.then(data => dispatch({ type: "SET_DATA", payload: data }));
};
Q11. What are selectors in Redux, and why use them?
Selectors extract specific data from the state:
const selectUserName = (state) => state.user.name;
Q12. How does Redux handle immutability in reducers?
Reducers always return new state objects:
return { ...state, count: state.count + 1 };
Q13. What are optimistic updates in state management?
- Update UI before server confirms success.
- Makes apps feel faster.
- Roll back if API fails.
Q14. How does client-side routing differ from server-side routing?
| Type | Description |
|---|---|
| Server-side routing | Each navigation loads a new page from the server. |
| Client-side routing | React Router updates the view without reloading the page. |
Q15. How do you implement nested routes?
<Route path="dashboard" element={<Dashboard />}>
<Route path="stats" element={<Stats />} />
</Route>
Q16. How do you redirect users in React Router v6 (vs useHistory)?
const navigate = useNavigate();
navigate("/login"); // replaces useHistory from v5
Q17. What are protected/private routes?
- Routes that require authentication.
function PrivateRoute({ children }) {
return isLoggedIn ? children : <Navigate to="/login" />;
}
Q18. How do you use dynamic route parameters?
<Route path="/user/:id" element={<User />} />
function User() {
const { id } = useParams();
return <h1>User ID: {id}</h1>;
}
Q19. What is the difference between <Link> and <NavLink>?
| Component | Purpose |
|---|---|
<Link> | Navigates to a route. |
<NavLink> | Same as <Link> but adds active class automatically. |
Q20. How do you handle 404 pages in React Router?
<Route path="*" element={<NotFound />} />
Q21. How do you pass state through navigation?
navigate("/profile", { state: { userId: 1 } });
Q22. How do you implement lazy-loaded routes?
const LazyPage = React.lazy(() => import("./Page"));
<Routepath="/lazy"
element={
<Suspense fallback={<div>Loading...</div>}>
<LazyPage />
</Suspense>
}
/>
