Tags: react, hooks, state, frontend, components, javascript
Level: intermediate
TL;DR: Quick reference for React fundamentals, component lifecycle via hooks, state management patterns, and common technical interview scenarios.
React uses a Virtual DOM to optimize rendering by batching updates and minimizing direct DOM manipulation.
Components are the building blocks, returning JSX to describe the UI based on current state and props.
Props are read-only arguments passed top-down from parent to child components.
State represents the mutable, component-specific data that triggers re-renders when updated.
Hooks (useState, useEffect) allow functional components to manage state and side effects.
The Context API provides a way to pass data through the component tree without prop drilling.
React relies on a one-way data flow (unidirectional data binding).
Q: How does the Virtual DOM work?R: It creates an in-memory representation of the real DOM. When state changes, React compares the new Virtual DOM with the old one (diffing) and updates only the changed nodes in the real DOM.
Q: What is the difference between state and props?R: I use props to pass data and configuration downwards from parents. I use state to manage local data that changes over time and affects the component's render.
Q: What happens if you provide an empty dependency array to useEffect?R: The effect will run exactly once after the initial render, acting similarly to componentDidMount in class components.
Q: Why do we need key props in React lists?R: I use keys to help React identify which items have changed, been added, or removed, allowing it to efficiently update the DOM without re-rendering the entire list.
Mutating state directly instead of using the state setter function (e.g., state.value = 1 instead of setState(1)).
Experiencing stale closures inside useEffect or useCallback by forgetting to include variables in the dependency array.
Causing infinite render loops by updating state synchronously inside a render function or an effect without proper dependencies.
Overusing the Context API for high-frequency state updates, leading to unnecessary re-renders across the tree.
// Basic state and effect pattern
import { useState, useEffect } from 'react';
export function UserProfile({ userId }) {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
let ignore = false;
async function fetchUser() {
setLoading(true);
const res = await fetch(`/api/users/${userId}`);
const data = await res.json();
if (!ignore) {
setUser(data);
setLoading(false);
}
}
fetchUser();
// Cleanup function to prevent race conditions
return () => { ignore = true; };
}, [userId]);
if (loading) return <div>Loading...</div>;
return <div>{user.name}</div>;
}
Bash
// Create a new React project using Vite
npm create vite@latest my-app -- --template react-ts