Toolmingo
Guides19 min read

50 React Interview Questions (With Answers)

Top React interview questions with clear answers and code examples — covering hooks, state management, performance, reconciliation, and modern React patterns.

React interviews test component thinking, hooks mastery, performance optimisation, and architectural knowledge. This guide covers the 50 most common questions — with concise answers and runnable code examples.

Quick reference

Topic Most asked questions
Fundamentals Virtual DOM, JSX, props vs state
Hooks useState, useEffect, useRef, custom hooks
Performance memo, useMemo, useCallback, lazy loading
Patterns Lifting state, composition, render props, HOC
Advanced Context, useReducer, reconciliation, concurrent

Fundamentals

1. What is the Virtual DOM and how does it work?

The Virtual DOM is an in-memory representation of the real DOM. React:

  1. Renders a virtual tree in memory
  2. Diffs the new tree against the previous one (reconciliation)
  3. Calculates the minimal set of DOM mutations
  4. Applies only those changes to the real DOM (commit phase)
// React calculates what changed and only updates <span>, not the whole list
function Counter() {
  const [count, setCount] = React.useState(0);
  return (
    <ul>
      <li>Static item</li>
      <li>Count: <span>{count}</span></li>
    </ul>
  );
}

This batches DOM writes and avoids expensive reflows for unchanged nodes.


2. What is JSX? Is it required?

JSX is syntactic sugar for React.createElement calls. It is not required but is used in almost every React codebase.

// JSX
const el = <h1 className="title">Hello</h1>;

// Compiles to (React 17- classic transform)
const el = React.createElement('h1', { className: 'title' }, 'Hello');

// React 17+ automatic transform — no import needed

3. What is the difference between props and state?

Props State
Owner Parent passes them Component owns them
Mutable? Read-only in child Updated via setter
Re-render When parent re-renders When setState is called
Usage Configuration / data down Internal interactive data
// props — parent-controlled
function Greeting({ name }) {
  return <p>Hello, {name}</p>;
}

// state — component-controlled
function Toggle() {
  const [on, setOn] = React.useState(false);
  return <button onClick={() => setOn(v => !v)}>{on ? 'ON' : 'OFF'}</button>;
}

4. What are controlled vs uncontrolled components?

Controlled: React state is the single source of truth for the input value.

function ControlledInput() {
  const [value, setValue] = React.useState('');
  return <input value={value} onChange={e => setValue(e.target.value)} />;
}

Uncontrolled: The DOM owns the value; you read it via a ref.

function UncontrolledInput() {
  const ref = React.useRef();
  const handleSubmit = () => console.log(ref.current.value);
  return <input ref={ref} defaultValue="" />;
}

Prefer controlled components — they make validation and derived state straightforward.


5. What is reconciliation?

Reconciliation is how React decides which DOM nodes to update. React uses two heuristics:

  1. Different element types → tear down the old tree, build a new one
  2. Same element type → update only changed attributes

Keys tell React which list items match across renders:

// Bad — React can't match items after reorder
items.map(item => <li>{item.name}</li>)

// Good — stable key lets React reuse DOM nodes
items.map(item => <li key={item.id}>{item.name}</li>)

6. What is the difference between class components and function components?

Class Function
State this.state / setState useState
Lifecycle componentDidMount etc. useEffect
Code reuse HOC / render props Custom hooks
this Required Not used
Status Legacy (still works) Recommended
// Class
class Counter extends React.Component {
  state = { count: 0 };
  render() {
    return <button onClick={() => this.setState(s => ({ count: s.count + 1 }))}>
      {this.state.count}
    </button>;
  }
}

// Function (preferred)
function Counter() {
  const [count, setCount] = React.useState(0);
  return <button onClick={() => setCount(c => c + 1)}>{count}</button>;
}

Hooks

7. What rules must hooks follow?

  1. Only call at the top level — not inside loops, conditions, or nested functions
  2. Only call from React functions — function components or custom hooks
// ❌ Wrong — conditional hook call
function Bad({ show }) {
  if (show) {
    const [x, setX] = useState(0); // breaks hook order
  }
}

// ✅ Correct
function Good({ show }) {
  const [x, setX] = useState(0);
  if (!show) return null;
  // …
}

8. Explain useState — when does a re-render happen?

useState returns [value, setter]. React schedules a re-render when the setter is called with a different value (using Object.is comparison).

const [count, setCount] = useState(0);

setCount(1);       // re-render (0 !== 1)
setCount(0);       // no re-render (0 === 0)
setCount(c => c + 1); // functional update — safe when depending on prev value

Object state: React compares by reference, so always return a new object:

// ❌ mutation — same reference, no re-render
setUser(user => { user.name = 'Alice'; return user; });

// ✅ new object
setUser(user => ({ ...user, name: 'Alice' }));

9. Explain useEffect and its dependency array

useEffect(fn, deps) runs fn after the render where deps changed.

deps Runs
Omitted After every render
[] Once after mount
[a, b] After mount + whenever a or b changes
useEffect(() => {
  const sub = subscribe(id);
  return () => sub.unsubscribe(); // cleanup on unmount or id change
}, [id]);

Common pitfall — missing a dependency causes stale closures:

// ❌ count is stale after first render
useEffect(() => {
  const id = setInterval(() => console.log(count), 1000);
  return () => clearInterval(id);
}, []); // count not in deps

// ✅ add count to deps
}, [count]);

10. What is useRef and when should you use it?

useRef returns a mutable { current } object that persists across renders without causing re-renders.

Use cases:

// 1. DOM access
const inputRef = useRef(null);
<input ref={inputRef} />
// inputRef.current.focus()

// 2. Mutable value that shouldn't trigger re-render (e.g. timer ID)
const timerId = useRef(null);
timerId.current = setTimeout(...);

// 3. Track previous value
function usePrevious(value) {
  const ref = useRef();
  useEffect(() => { ref.current = value; });
  return ref.current; // previous render's value
}

11. What is useContext and when should you avoid it?

useContext subscribes a component to a context value. Every consumer re-renders when the context value changes.

const ThemeContext = React.createContext('light');

function App() {
  return (
    <ThemeContext.Provider value="dark">
      <Button />
    </ThemeContext.Provider>
  );
}

function Button() {
  const theme = useContext(ThemeContext); // 'dark'
  return <button className={theme}>Click</button>;
}

Avoid context for frequently-changing values (e.g. mouse position) — it re-renders all consumers. Prefer Zustand, Jotai, or Redux for high-frequency state.


12. What is useReducer and when is it better than useState?

useReducer(reducer, initialState) is useState with explicit actions — better when:

  • State has multiple sub-values that update together
  • Next state depends on previous state in a complex way
  • You want to centralise update logic
const initialState = { count: 0, step: 1 };

function reducer(state, action) {
  switch (action.type) {
    case 'increment': return { ...state, count: state.count + state.step };
    case 'setStep':   return { ...state, step: action.payload };
    default: throw new Error('Unknown action');
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);
  return (
    <>
      <p>{state.count}</p>
      <button onClick={() => dispatch({ type: 'increment' })}>+</button>
      <input
        type="number"
        value={state.step}
        onChange={e => dispatch({ type: 'setStep', payload: +e.target.value })}
      />
    </>
  );
}

13. What is useMemo?

useMemo memoises the return value of a function. Re-runs only when dependencies change.

const sortedList = useMemo(
  () => [...items].sort((a, b) => a.name.localeCompare(b.name)),
  [items]
);

Use when the computation is genuinely expensive. Don't useMemo everything — the comparison overhead costs too.


14. What is useCallback?

useCallback memoises a function reference. Useful to prevent child re-renders when passing callbacks as props.

// Without useCallback — new function reference on every parent render
// → Child re-renders even when nothing changed

const handleDelete = useCallback(
  (id) => setItems(items => items.filter(item => item.id !== id)),
  [] // stable reference; functional update so items not needed as dep
);

<ExpensiveChild onDelete={handleDelete} />

15. What are custom hooks?

A custom hook is a function starting with use that calls other hooks. It extracts and reuses stateful logic without sharing component state.

function useFetch(url) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    let cancelled = false;
    fetch(url)
      .then(r => r.json())
      .then(d => { if (!cancelled) setData(d); })
      .catch(e => { if (!cancelled) setError(e); })
      .finally(() => { if (!cancelled) setLoading(false); });
    return () => { cancelled = true; };
  }, [url]);

  return { data, loading, error };
}

// Usage
const { data, loading } = useFetch('/api/users');

Performance

16. What is React.memo?

React.memo is a HOC that skips re-rendering a function component if its props are shallowly equal to the previous render.

const Avatar = React.memo(function Avatar({ name, src }) {
  return <img src={src} alt={name} />;
});

// Only re-renders when name or src actually changes

Custom comparison:

const Avatar = React.memo(Avatar, (prev, next) => prev.id === next.id);

17. Explain reconciliation keys and why index keys are bad

Using array indexes as keys causes bugs when the list order changes:

// ❌ index key — React reuses wrong DOM nodes after sort/insert
items.map((item, i) => <Row key={i} data={item} />)

// ✅ stable unique ID
items.map(item => <Row key={item.id} data={item} />)

When the list is reordered, index keys trick React into thinking existing components only changed their props — causing state (e.g. input values) to persist on the wrong item.


18. What is lazy loading and Suspense?

React.lazy defers loading a component until it's first rendered. Suspense shows a fallback while loading.

const HeavyChart = React.lazy(() => import('./HeavyChart'));

function Dashboard() {
  return (
    <Suspense fallback={<p>Loading chart…</p>}>
      <HeavyChart />
    </Suspense>
  );
}

This splits the bundle so the initial JS is smaller.


19. What causes unnecessary re-renders?

  1. Parent re-renders → all children re-render by default
  2. Context value changes → all consumers re-render
  3. New object/function reference passed as prop on every render
  4. useState setter called with same value (batched, no render in practice since React 18)

Fixes: React.memo, useMemo, useCallback, stable context values, splitting context.


20. What is the React Profiler?

The React DevTools Profiler records which components rendered and how long each took. Use it to find hot paths before optimising — don't guess.

// Programmatic profiling
<Profiler id="Chart" onRender={(id, phase, duration) => {
  console.log(`${id} ${phase}: ${duration}ms`);
}}>
  <HeavyChart />
</Profiler>

Component patterns

21. What is prop drilling and how do you avoid it?

Prop drilling is passing props through many intermediate components that don't use them.

Solutions:

  1. Context — for genuinely global data (theme, user, locale)
  2. State management library — Zustand, Jotai, Redux
  3. Component composition — pass components as children instead of data
// Composition avoids drilling — parent renders children directly
function Layout({ sidebar, content }) {
  return (
    <div className="layout">
      <aside>{sidebar}</aside>
      <main>{content}</main>
    </div>
  );
}

<Layout
  sidebar={<Nav user={user} />}
  content={<Feed posts={posts} />}
/>

22. What is lifting state up?

When two sibling components need to share state, move that state to their closest common ancestor and pass it down via props.

function Parent() {
  const [query, setQuery] = useState('');
  return (
    <>
      <SearchInput value={query} onChange={setQuery} />
      <ResultsList query={query} />
    </>
  );
}

23. What are Higher-Order Components (HOC)?

A HOC is a function that takes a component and returns a new component with added behaviour.

function withAuth(WrappedComponent) {
  return function AuthGuard(props) {
    const { user } = useAuth();
    if (!user) return <Redirect to="/login" />;
    return <WrappedComponent {...props} />;
  };
}

const ProtectedDashboard = withAuth(Dashboard);

Custom hooks cover most HOC use cases today, but HOCs are still used in some libraries (Redux connect, React Router withRouter).


24. What is the render props pattern?

Passing a function as a prop to share rendering logic.

function MouseTracker({ render }) {
  const [pos, setPos] = useState({ x: 0, y: 0 });
  return (
    <div onMouseMove={e => setPos({ x: e.clientX, y: e.clientY })}>
      {render(pos)}
    </div>
  );
}

<MouseTracker render={pos => <p>Mouse at {pos.x}, {pos.y}</p>} />

Custom hooks largely replaced this pattern.


25. What is the children prop?

props.children is anything nested between a component's opening and closing tags.

function Card({ title, children }) {
  return (
    <div className="card">
      <h2>{title}</h2>
      {children}
    </div>
  );
}

<Card title="Welcome">
  <p>Content here</p>
  <button>Action</button>
</Card>

State management

26. When should you use a global state library vs Context?

Scenario Solution
Theme / locale / current user Context (rarely changes)
Frequently updated shared state Zustand / Jotai
Complex async flows, devtools Redux Toolkit
Server state (caching, refetch) TanStack Query / SWR

27. What is TanStack Query (React Query) used for?

It manages server state — fetching, caching, background refetching, and synchronisation — so you don't have to build that yourself.

const { data, isLoading, error } = useQuery({
  queryKey: ['user', userId],
  queryFn: () => fetch(`/api/users/${userId}`).then(r => r.json()),
  staleTime: 60_000, // treat as fresh for 60s
});

Compare to manual useEffect fetching: React Query gives you caching, deduplication, refetch on focus, optimistic updates, and more for free.


28. What is Zustand?

A minimal, unopinionated state management library with a simple store API.

import { create } from 'zustand';

const useStore = create(set => ({
  count: 0,
  increment: () => set(state => ({ count: state.count + 1 })),
}));

function Counter() {
  const { count, increment } = useStore();
  return <button onClick={increment}>{count}</button>;
}

Forms

29. How do you handle forms in React?

Option 1: Controlled (vanilla)

function Form() {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');

  const handleSubmit = e => {
    e.preventDefault();
    loginUser({ email, password });
  };

  return (
    <form onSubmit={handleSubmit}>
      <input value={email} onChange={e => setEmail(e.target.value)} type="email" />
      <input value={password} onChange={e => setPassword(e.target.value)} type="password" />
      <button type="submit">Login</button>
    </form>
  );
}

Option 2: React Hook Form (preferred for complex forms)

import { useForm } from 'react-hook-form';

function Form() {
  const { register, handleSubmit, formState: { errors } } = useForm();
  return (
    <form onSubmit={handleSubmit(data => console.log(data))}>
      <input {...register('email', { required: true, pattern: /\S+@\S+\.\S+/ })} />
      {errors.email && <span>Invalid email</span>}
      <button type="submit">Submit</button>
    </form>
  );
}

Routing

30. How does React Router v6 work?

import { BrowserRouter, Routes, Route, Link, useParams, useNavigate } from 'react-router-dom';

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/users/:id" element={<UserPage />} />
        <Route path="*" element={<NotFound />} />
      </Routes>
    </BrowserRouter>
  );
}

function UserPage() {
  const { id } = useParams();
  const navigate = useNavigate();
  return <button onClick={() => navigate('/')}>Back</button>;
}

Advanced React

31. What is the React Fiber architecture?

Fiber (introduced in React 16) is a complete rewrite of the reconciliation engine. Key improvements:

  • Incremental rendering: break work into units, pause and resume
  • Priority scheduling: urgent updates (user input) can interrupt lower-priority work
  • Concurrency: foundation for Concurrent Mode, Suspense, and transitions

32. What is Concurrent React?

Concurrent React (React 18+) allows React to prepare multiple UI versions simultaneously without blocking the main thread.

Key APIs:

import { startTransition, useTransition, useDeferredValue } from 'react';

// Mark an update as non-urgent
startTransition(() => setSearchQuery(value));

// Show pending indicator
const [isPending, startTransition] = useTransition();

// Defer a derived value during fast typing
const deferredQuery = useDeferredValue(searchQuery);

33. What is useTransition?

It marks state updates as non-urgent so React can keep the UI responsive during them.

function SearchPage() {
  const [query, setQuery] = useState('');
  const [results, setResults] = useState([]);
  const [isPending, startTransition] = useTransition();

  function handleChange(e) {
    const value = e.target.value;
    setQuery(value); // urgent: update input immediately

    startTransition(() => {
      setResults(expensiveSearch(value)); // non-urgent: can be interrupted
    });
  }

  return (
    <>
      <input value={query} onChange={handleChange} />
      {isPending ? <Spinner /> : <ResultList data={results} />}
    </>
  );
}

34. What are Error Boundaries?

Error boundaries catch JavaScript errors in their child tree and display a fallback UI instead of crashing the app. They must be class components.

class ErrorBoundary extends React.Component {
  state = { hasError: false };

  static getDerivedStateFromError() {
    return { hasError: true };
  }

  componentDidCatch(error, info) {
    logErrorToService(error, info.componentStack);
  }

  render() {
    if (this.state.hasError) return <h2>Something went wrong.</h2>;
    return this.props.children;
  }
}

<ErrorBoundary>
  <SuspiciousComponent />
</ErrorBoundary>

35. What is forwardRef?

forwardRef lets a component pass a ref down to a DOM element inside it.

const FancyInput = React.forwardRef(function FancyInput(props, ref) {
  return <input ref={ref} className="fancy" {...props} />;
});

// Parent can now focus the inner input
const ref = useRef();
<FancyInput ref={ref} />
ref.current.focus();

36. What is useImperativeHandle?

Used with forwardRef to expose a custom imperative API instead of the raw DOM node.

const VideoPlayer = forwardRef(function VideoPlayer(props, ref) {
  const videoRef = useRef();

  useImperativeHandle(ref, () => ({
    play: () => videoRef.current.play(),
    pause: () => videoRef.current.pause(),
  }));

  return <video ref={videoRef} {...props} />;
});

// Parent uses clean API
playerRef.current.play();

37. What are portals?

Portals render children into a different DOM node — useful for modals and tooltips that need to escape overflow/z-index constraints.

import { createPortal } from 'react-dom';

function Modal({ children }) {
  return createPortal(
    <div className="modal-overlay">{children}</div>,
    document.getElementById('modal-root')
  );
}

The component is still in the React tree (events bubble normally) but renders outside its DOM parent.


38. What are Server Components?

React Server Components (RSC) run only on the server — they have zero JS bundle cost and can directly access databases, files, and secrets.

// app/users/page.tsx (Next.js App Router — Server Component by default)
async function UsersPage() {
  const users = await db.user.findMany(); // direct DB access, not exposed to client
  return <ul>{users.map(u => <li key={u.id}>{u.name}</li>)}</ul>;
}

Client Components are opted in with 'use client'. Server Components cannot use hooks or browser APIs.


39. Explain the React render lifecycle (class components)

Mount:   constructor → render → DOM update → componentDidMount
Update:  shouldComponentUpdate → render → DOM update → componentDidUpdate
Unmount: componentWillUnmount

For function components, useEffect maps roughly to:

[]     → componentDidMount + componentWillUnmount (cleanup)
[dep]  → componentDidMount + componentDidUpdate (when dep changes) + cleanup

40. What is StrictMode?

React.StrictMode wraps your app in development to:

  • Double-invoke render functions to detect side effects in render
  • Double-invoke effects to catch missing cleanup
  • Warn on deprecated APIs
<React.StrictMode>
  <App />
</React.StrictMode>

No effect in production builds.


TypeScript with React

41. How do you type component props in TypeScript?

interface ButtonProps {
  label: string;
  onClick: () => void;
  variant?: 'primary' | 'secondary';
  disabled?: boolean;
}

function Button({ label, onClick, variant = 'primary', disabled = false }: ButtonProps) {
  return <button onClick={onClick} disabled={disabled} className={variant}>{label}</button>;
}

42. How do you type events in React TypeScript?

// Input change
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
  setValue(e.target.value);
};

// Form submit
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
  e.preventDefault();
};

// Button click
const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {
  e.preventDefault();
};

43. How do you type useState in TypeScript?

TypeScript infers the type from the initial value. Use a generic when the type is wider than the initial value.

const [count, setCount] = useState(0);                    // number inferred
const [user, setUser] = useState<User | null>(null);      // explicit generic
const [items, setItems] = useState<string[]>([]);         // array

44. How do you type a custom hook?

interface FetchResult<T> {
  data: T | null;
  loading: boolean;
  error: Error | null;
}

function useFetch<T>(url: string): FetchResult<T> {
  const [data, setData] = useState<T | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<Error | null>(null);

  useEffect(() => {
    fetch(url)
      .then(r => r.json() as Promise<T>)
      .then(setData)
      .catch(setError)
      .finally(() => setLoading(false));
  }, [url]);

  return { data, loading, error };
}

Testing

45. How do you test React components?

The standard tool is React Testing Library (RTL), which tests from the user's perspective.

import { render, screen, fireEvent } from '@testing-library/react';
import userEvent from '@testing-library/user-event';

test('increments counter on click', async () => {
  render(<Counter />);
  const button = screen.getByRole('button', { name: /increment/i });
  await userEvent.click(button);
  expect(screen.getByText('1')).toBeInTheDocument();
});

46. What is the difference between getBy, queryBy, and findBy in RTL?

Query When found When not found Async?
getBy* Element Throws No
queryBy* Element Returns null No
findBy* Element Rejects (timeout) Yes
// Assert element doesn't exist — use queryBy
expect(screen.queryByText('Loading…')).not.toBeInTheDocument();

// Wait for element to appear — use findBy
const heading = await screen.findByRole('heading');

Common interview gotchas

47. Why shouldn't you call hooks conditionally?

React maintains hook state by call order. If you skip a hook call (e.g. inside an if), all subsequent hooks get the wrong state.

// ❌ Breaks hook order on re-render
if (user) {
  const [name, setName] = useState(user.name); // hook 1 in some renders, hook 2 in others
}
const [count, setCount] = useState(0);

// ✅ Always call, conditionally use
const [name, setName] = useState(user?.name ?? '');

48. What is a stale closure in React?

A stale closure is when a callback or effect captures a value from an old render and never gets the updated value.

// ❌ Stale closure — count is always 0 inside the interval
useEffect(() => {
  const id = setInterval(() => console.log(count), 1000);
  return () => clearInterval(id);
}, []); // count not in deps

// ✅ Fix 1: add to deps (re-creates interval on each count change)
}, [count]);

// ✅ Fix 2: use a ref to always read latest value
const countRef = useRef(count);
countRef.current = count;
useEffect(() => {
  const id = setInterval(() => console.log(countRef.current), 1000);
  return () => clearInterval(id);
}, []);

49. Why does 0 && <Component /> render 0?

Logical AND (&&) returns the first falsy value. 0 is falsy but React renders numbers.

// ❌ Renders literal "0" when count is 0
{count && <Badge count={count} />}

// ✅ Use explicit boolean
{count > 0 && <Badge count={count} />}
{!!count && <Badge count={count} />}
{count ? <Badge count={count} /> : null}

50. What is the difference between useEffect and useLayoutEffect?

useEffect useLayoutEffect
When After browser paint After DOM update, before paint
Thread Asynchronous Synchronous (blocks paint)
Use for Data fetching, subscriptions DOM measurements, animations
// Measure element after DOM update, before user sees flicker
useLayoutEffect(() => {
  const { width } = ref.current.getBoundingClientRect();
  setWidth(width);
}, []);

Prefer useEffectuseLayoutEffect blocks paint and can degrade perceived performance.


Common mistakes

Mistake Problem Fix
Using index as key Incorrect state on reorder Use stable unique ID
Mutating state directly No re-render Return new object/array
Missing useEffect deps Stale closure bugs Add all referenced values
0 && in JSX Renders literal 0 Use count > 0 && or ternary
Calling hooks conditionally Hook order breaks Always call hooks at top level
useEffect for derived state Double render Compute value inline / use useMemo
Over-memoising everything Hidden bugs, harder to debug Profile first, memo only hot paths
Setting state in render Infinite loop Use useEffect or compute inline

FAQ

Q: When should I use useEffect vs event handlers for side effects?
A: Prefer event handlers (onClick, onSubmit) for user-initiated side effects. Reserve useEffect for effects caused by rendering itself — syncing with external systems, subscriptions, timers.

Q: What's the difference between React.memo and useMemo?
A: React.memo wraps a component to skip re-renders when props are unchanged. useMemo memoises a value inside a component.

Q: Is useCallback always necessary when passing functions to children?
A: Only when the child is wrapped in React.memo. Otherwise the function reference instability doesn't cause extra renders. Measure with the Profiler before adding useCallback.

Q: How does React batch state updates?
A: React 18 batches all state updates automatically — inside event handlers, setTimeout, fetch callbacks, and anywhere else. Before React 18, only event handlers were batched.

Q: What is the difference between key on a list item vs on a component to force reset?
A: key on a list item helps React match items across renders. But you can also use key on a non-list component to completely reset its state — changing key unmounts and remounts the component.

Q: Should I use class components in 2024?
A: No, unless you need Error Boundaries (must be class) or you're maintaining legacy code. All new development should use function components and hooks.

Related tools

Keep reading

All Toolmingotools are free & run in your browser

No sign-up, no upload, no watermark. Your files never leave your device.

Browse all tools