Irbisa · Cheatsheet

Rendering & Reconciliation

What triggers a render, render vs commit, reconciliation and keys, Fiber, concurrent rendering, transitions, Suspense, hydration

Senior Developer · 20 questions

  1. 01

    What causes a React component to re-render?

    A component renders when its own state changes, when its parent renders, or when a context it reads changes.

  2. 02

    What is the difference between a React element, a component and a component instance?

    A component is the function you write; an element is the plain, immutable object (type, props, key) that JSX creates to describe what to render; an instance is what React keeps for an element mounted at a position in the tree, a fiber that holds its state, hooks and effects.

    function Avatar({ name }: { name: string }) {  const [expanded, setExpanded] = useState(false);  return <button onClick={() => setExpanded(true)}>{expanded ? name : name[0]}</button>;} const element = <Avatar name="Ada" />;…
  3. 03

    What is the difference between the render phase and the commit phase in React?

    In the render phase React calls your components and works out what changed; in the commit phase it applies those changes to the DOM and runs refs and effects.

  4. 04

    In what order do these logs appear on mount (without StrictMode), and why?

    function Child() {  console.log('Child render');  useLayoutEffect(() => console.log('Child layout effect'), []);  useEffect(() => console.log('Child effect'), []);  return <p>child</p>;} function Parent() {  console.log('Parent render');  useLayoutEffect(() => console.log('Parent layout effect'), []);  useEffect(() => console.log('Parent effect'), []);  return <Child />;}

    Parent render, Child render, Child layout effect, Parent layout effect, Child effect, Parent effect.

  5. 05

    What is reconciliation, and which heuristics does React use to diff two element trees?

    Reconciliation compares the element tree of a new render with the previous one to decide which DOM nodes to keep, update or replace.

    function Page({ isAdmin }: { isAdmin: boolean }) {  // same type at the same position: Panel keeps its state when isAdmin flips  return isAdmin ? <Panel title="Admin" /> : <Panel title="User" />;} function Card({ boxed }: { boxed: boolean }) {…
  6. 06

    How many times does Expensive log after the button is clicked three times, and why?

    function Expensive() {  console.log('Expensive render');  return <p>Heavy chart</p>;} function Counter({ children }: { children: React.ReactNode }) {  const [count, setCount] = useState(0);  return (    <div>      <button onClick={() => setCount(count + 1)}>Clicked {count}</button>      {children}    </div>  );} export default function App() {  return <Counter><Expensive /></Counter>;}

    Once, on mount: Expensive is created by App and reaches Counter as children, so when Counter re-renders, children is the same element object and React skips it.

  7. 07

    What happens if you call a state setter during render, and when is that a legitimate pattern?

    React discards the output the component just returned and re-runs it at once with the new state, before rendering its children or committing.

    function List({ items }: { items: Item[] }) {  const [selection, setSelection] = useState<Item | null>(null);  const [prevItems, setPrevItems] = useState(items);   if (items !== prevItems) {    // runs once per change; React re-runs List before rendering its children…
  8. 08

    What is concurrent rendering, and what changed with React 18?

    Concurrent rendering lets React prepare a new UI in the background, pause it to handle something more urgent, and throw it away if it is no longer needed.

  9. 09

    How does an update inside startTransition render differently from an urgent update, and what happens if the user types while it is rendering?

    An urgent update renders synchronously and commits before the next frame; a transition renders in the background, can be interrupted, and keeps the current UI until it is ready.

    function SearchPage() {  const [text, setText] = useState('');  const [query, setQuery] = useState('');  const [isPending, startTransition] = useTransition();   return (…
  10. 10

    What does useDeferredValue do, and when would you use it instead of debouncing?

    useDeferredValue(value) returns the previous value during an urgent render and then re-renders in the background with the new one, so a slow part of the UI lags behind fast input without blocking it.

    const SlowList = memo(function SlowList({ query }: { query: string }) {  const items = filterHugeList(query); // expensive  return <ul>{items.map((item) => <li key={item.id}>{item.name}</li>)}</ul>;}); function Search() {…
  11. 11

    What happens inside React when a component suspends, and what did React 19 change about it?

    A component suspends when it reads something still loading: React stops rendering that subtree, shows the closest Suspense boundary's fallback, and retries the render when the awaited promise resolves.

    const Comments = lazy(() => import('./Comments')); function Post({ postPromise }: { postPromise: Promise<PostData> }) {  const post = use(postPromise); // suspends until resolved  return (    <article>…
  12. 12

    What is hydration, and what does selective hydration add in React 18 and later?

    Hydration is when React on the client takes server-rendered HTML, builds its component tree over the existing DOM and attaches event handlers instead of recreating the DOM.

    // entry: attach to the server HTML instead of creating new DOMhydrateRoot(document.getElementById('root')!, <App />); function LocalTime() {  // wrong: the server and the client format different times  // return <span>{new Date().toLocaleTimeString()}</span>;…
  13. 13

    What is React Fiber, and what problem did it solve?

    Fiber is React's reconciler since version 16: each element instance becomes a fiber node, a unit of work React can pause, resume or discard.

  14. 14

    How does React reconcile a reordered keyed list, and which reorder is the most expensive for it?

    React walks the new children left to right, reuses the fiber with the same key, and moves a DOM node only when its item now comes after one that used to follow it.

  15. 15

    How does React schedule and prioritise updates internally: what are lanes and time slicing?

    Every update is assigned a lane, a bit in a bitmask that encodes its priority, and React always renders the most urgent pending lanes first.

  16. 16

    What are signals in Solid, Preact or Angular, and why does React re-render components instead of using fine-grained updates?

    A signal is a reactive value that records who reads it: when it changes, only the effects and DOM bindings that read it update, and the component function does not run again.

    type Effect = () => void;let running: Effect | null = null; function createSignal<T>(value: T) {  const subscribers = new Set<Effect>();  const read = () => {…
  17. 17

    Why does a navigation wrapped in a transition keep the old page on screen instead of showing a Suspense fallback, and how do you control which fallbacks appear?

    During a transition React refuses to hide content that is already visible: if the new screen suspends inside a boundary that is already showing content, React keeps the old UI (with isPending true) until the data arrives.

    function App() {  const [page, setPage] = useState('/');  const [isPending, startTransition] = useTransition();   function navigate(url: string) {    // keeps the current page on screen while the next one loads…
  18. 18

    Find the bug: the tab switch is wrapped in startTransition, yet after the await the old tab disappears and a Suspense fallback flashes.

    function Tabs() {  const [tab, setTab] = useState<'about' | 'posts'>('about');  const [isPending, startTransition] = useTransition();   function selectTab(next: 'about' | 'posts') {    startTransition(async () => {      await saveLastTab(next);      setTab(next);    });  }   return (    <>      <TabBar active={tab} pending={isPending} onSelect={selectTab} />      <Suspense fallback={<Spinner />}>{tab === 'about' ? <About /> : <Posts />}</Suspense>    </>  );}

    setTab runs after the await, outside the synchronous scope of startTransition, so React treats it as an ordinary urgent update.

  19. 19

    What does flushSync do, and when is it actually needed?

    flushSync(fn) from react-dom renders and commits the updates made inside fn synchronously, so the DOM is updated when it returns.

    import { flushSync } from 'react-dom'; function Chat() {  const [messages, setMessages] = useState<Message[]>([]);  const listRef = useRef<HTMLUListElement>(null);…
  20. 20

    What happens when a component throws during render, and what are onCaughtError, onUncaughtError and onRecoverableError in React 19?

    React unwinds to the nearest error boundary and renders its fallback; with no boundary it unmounts the whole root and the page goes blank.

    import { createRoot } from 'react-dom/client'; const root = createRoot(document.getElementById('root')!, {  onCaughtError(error, errorInfo) {    report(error, { componentStack: errorInfo.componentStack, handled: true });  },…