Episode 2 — React Frontend Architecture NextJS / 2.4 — React Lifecycle Methods

2.4 — React Lifecycle Methods: Quick Revision

Compact cheat sheet. Print-friendly.

How to use this material

  1. Read through once after completing all sub-topics
  2. Use before interviews or code reviews
  3. Star (⭐) items you keep forgetting
  4. Quiz yourself by covering the right column

Class Components

ConceptKey Point
Minimum class componentclass X extends Component { render() { return <div/> } }
Constructorconstructor(props) { super(props); this.state = {...} }
Class field syntaxstate = {...} — no constructor needed
this bindingUse arrow class fields: handleClick = () => {}
setState is asyncconsole.log(this.state) after setState shows OLD value
setState mergessetState({b:2}) preserves a and c in {a,b,c}
Updater formsetState(prev => ({count: prev.count + 1})) for derived updates
render() must be pureNo setState, no side effects, no DOM access

Lifecycle Methods — Mounting

constructor → getDerivedStateFromProps → render → DOM update → componentDidMount
MethodPurposeCan setState?
constructorInit state, bind methodsAssign only
getDerivedStateFromPropsSync state from props (rare)Return obj
renderReturn JSX
componentDidMountFetch, subscribe, measure DOM

Lifecycle Methods — Updating

getDerivedStateFromProps → shouldComponentUpdate → render → getSnapshotBeforeUpdate → DOM → componentDidUpdate
MethodPurposeCan setState?
shouldComponentUpdateSkip render if nothing changed
getSnapshotBeforeUpdateCapture DOM before update
componentDidUpdateReact to changes, fetch✅ (guarded!)

Lifecycle Methods — Unmounting & Error

MethodPurpose
componentWillUnmountClean up timers, listeners, connections
getDerivedStateFromErrorShow fallback UI
componentDidCatchLog error to service

Deprecated Methods

DeprecatedUse Instead
componentWillMountconstructor / componentDidMount
componentWillReceivePropscomponentDidUpdate / getDerivedStateFromProps
componentWillUpdategetSnapshotBeforeUpdate

useEffect — Three Configurations

// Every render
useEffect(() => { ... });

// Mount only
useEffect(() => { ... return () => cleanup; }, []);

// When deps change
useEffect(() => { ... return () => cleanup; }, [dep1, dep2]);
ConfigWhen it runsCleanup runs
No depsEvery renderBefore each re-run + unmount
[]Mount onlyUnmount only
[dep]Mount + when dep changesBefore re-run + unmount

useEffect Key Rules

RuleDetail
Runs after paintAsync — user sees render before effect
Cleanup before re-runOld cleanup runs before new effect
Object.is comparisonObjects/arrays = new reference = re-run
Can't be asyncDefine async function inside, call it
Strict Mode runs twiceFind missing cleanup — don't disable

Lifecycle → useEffect Mapping

ClassHook
componentDidMountuseEffect(fn, [])
componentDidUpdate(prev)useEffect(fn, [dep])
componentWillUnmountCleanup: return () => {} in useEffect
shouldComponentUpdateReact.memo

Data Fetching Pattern

useEffect(() => {
  const ctrl = new AbortController();
  fetch(url, { signal: ctrl.signal })
    .then(r => r.json())
    .then(setData)
    .catch(e => e.name !== 'AbortError' && setError(e.message));
  return () => ctrl.abort();
}, [url]);

Cleanup Checklist

SetupCleanup
addEventListenerremoveEventListener
setIntervalclearInterval
setTimeoutclearTimeout
fetchAbortController.abort()
WebSocket().close()
observer.observe().disconnect()
subscribe()unsubscribe()

useEffect vs useLayoutEffect

useEffectuseLayoutEffect
TimingAfter paintBefore paint
BlockingNoYes
Use for99% of effectsDOM measurement, preventing flicker

When NOT to Use useEffect

SituationUse Instead
Derived/computed valuesCompute in render / useMemo
Event responsesEvent handlers
Reset state on prop changekey prop
App initialisationCode outside component

Core Formulas

Lifecycle = Mount → Update → Unmount
useEffect(setup, deps) → cleanup on re-run + unmount
PureComponent = auto shallow comparison
Error Boundary = getDerivedStateFromError + componentDidCatch
Race prevention = AbortController.abort() in cleanup