2.4 — React Lifecycle Methods: Quick Revision
Compact cheat sheet. Print-friendly.
How to use this material
- Read through once after completing all sub-topics
- Use before interviews or code reviews
- Star (⭐) items you keep forgetting
- Quiz yourself by covering the right column
Class Components
| Concept | Key Point |
|---|
| Minimum class component | class X extends Component { render() { return <div/> } } |
| Constructor | constructor(props) { super(props); this.state = {...} } |
| Class field syntax | state = {...} — no constructor needed |
this binding | Use arrow class fields: handleClick = () => {} |
setState is async | console.log(this.state) after setState shows OLD value |
setState merges | setState({b:2}) preserves a and c in {a,b,c} |
| Updater form | setState(prev => ({count: prev.count + 1})) for derived updates |
| render() must be pure | No setState, no side effects, no DOM access |
Lifecycle Methods — Mounting
constructor → getDerivedStateFromProps → render → DOM update → componentDidMount
| Method | Purpose | Can setState? |
|---|
constructor | Init state, bind methods | Assign only |
getDerivedStateFromProps | Sync state from props (rare) | Return obj |
render | Return JSX | ❌ |
componentDidMount | Fetch, subscribe, measure DOM | ✅ |
Lifecycle Methods — Updating
getDerivedStateFromProps → shouldComponentUpdate → render → getSnapshotBeforeUpdate → DOM → componentDidUpdate
| Method | Purpose | Can setState? |
|---|
shouldComponentUpdate | Skip render if nothing changed | ❌ |
getSnapshotBeforeUpdate | Capture DOM before update | ❌ |
componentDidUpdate | React to changes, fetch | ✅ (guarded!) |
Lifecycle Methods — Unmounting & Error
| Method | Purpose |
|---|
componentWillUnmount | Clean up timers, listeners, connections |
getDerivedStateFromError | Show fallback UI |
componentDidCatch | Log error to service |
Deprecated Methods
| Deprecated | Use Instead |
|---|
componentWillMount | constructor / componentDidMount |
componentWillReceiveProps | componentDidUpdate / getDerivedStateFromProps |
componentWillUpdate | getSnapshotBeforeUpdate |
useEffect — Three Configurations
useEffect(() => { ... });
useEffect(() => { ... return () => cleanup; }, []);
useEffect(() => { ... return () => cleanup; }, [dep1, dep2]);
| Config | When it runs | Cleanup runs |
|---|
| No deps | Every render | Before each re-run + unmount |
[] | Mount only | Unmount only |
[dep] | Mount + when dep changes | Before re-run + unmount |
useEffect Key Rules
| Rule | Detail |
|---|
| Runs after paint | Async — user sees render before effect |
| Cleanup before re-run | Old cleanup runs before new effect |
Object.is comparison | Objects/arrays = new reference = re-run |
| Can't be async | Define async function inside, call it |
| Strict Mode runs twice | Find missing cleanup — don't disable |
Lifecycle → useEffect Mapping
| Class | Hook |
|---|
componentDidMount | useEffect(fn, []) |
componentDidUpdate(prev) | useEffect(fn, [dep]) |
componentWillUnmount | Cleanup: return () => {} in useEffect |
shouldComponentUpdate | React.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
| Setup | Cleanup |
|---|
addEventListener | removeEventListener |
setInterval | clearInterval |
setTimeout | clearTimeout |
fetch | AbortController.abort() |
WebSocket() | .close() |
observer.observe() | .disconnect() |
subscribe() | unsubscribe() |
useEffect vs useLayoutEffect
| useEffect | useLayoutEffect |
|---|
| Timing | After paint | Before paint |
| Blocking | No | Yes |
| Use for | 99% of effects | DOM measurement, preventing flicker |
When NOT to Use useEffect
| Situation | Use Instead |
|---|
| Derived/computed values | Compute in render / useMemo |
| Event responses | Event handlers |
| Reset state on prop change | key prop |
| App initialisation | Code 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