Frontend & browser·topic 4 of 13
State, data and re-rendering
Where the data lives, who owns it, and what happens on screen when it changes. Most component bugs are ownership bugs wearing a costume, and most of the fixes have names that make the argument short.
Read in order · tick what you already know
- 01
the value only exists because this screen is open, and nobody else in the world needs to know about it.
Client state
- 02
the data on screen is a copy of something you do not own, and it went out of date while you were looking at it.
Server state
- 03
the same value was stored in two places and they drifted apart, so the header and the sidebar disagreed.
Single source of truth
- 04
you stored the filtered list in state as well as the raw list, and now they need keeping in sync.
Derived state
- 05
you needed to reach outside the component — to the DOM, a socket, a timer — after the render finished.
Effect
- 06
two sibling components needed the same value, so you moved it into the parent they share.
Lifting state up
- 07
you threaded the same value through four components that do not use it, just to reach the fifth.
Prop drilling
- 08
you put the value at the top of the tree so anything below could read it without being passed it.
Context provider
- 09
the field's value comes from state and every keystroke goes through your change handler before it appears.
Controlled input
- 10
you let the DOM keep the value and only read it out when the form was submitted.
Uncontrolled input
- 11
you track whether the form has been touched so you can warn before the user navigates away.
Dirty state
- 12
two screens asking for the same data shared one request because they named it the same way.
Query key
- 13
the cached data renders instantly and a background request quietly replaces it a moment later.
Revalidation
- 14
the item appeared in the list the instant you clicked, before the server had confirmed anything.
Optimistic UI
- 15
the second request could not start until the first finished, because the component that made it had not rendered yet.
Request waterfall
- 16
you typed fast and the results for an earlier query arrived last and overwrote the right ones.
Out-of-order response
- 17
you wrapped the slow part in a boundary and the rest of the page rendered without waiting for it.
Suspense boundary
- 18
you show grey blocks the shape of the content instead of a spinner while the data loads.
Skeleton screen
- 19
one component threw and you showed a fallback for that section instead of a blank white page.
Error boundary
- 20
you built a new array with the change in it instead of pushing onto the one you already had.
Immutable update
- 21
you replaced five interacting `setState` calls with one function that takes the current state and an action.
Reducer
- 22
the value lives outside the component tree and components subscribe to just the slice they read.
External store
- 23
the component subscribes to one field of the store, so changes to the rest do not wake it up.
Selector
- 24
you store each record once by id and keep lists as arrays of ids rather than nested copies.
Normalised state
- 25
you left a value out of the array to stop the loop and the effect started using an old copy of it.
Dependency array
- 26
you wrapped the component so it skips re-rendering when its props are shallowly the same.
Component memoisation
- 27
the list has fifty thousand rows and only the thirty on screen exist in the DOM at any moment.
List virtualisation
- 28
you watch a sentinel element near the bottom and fetch the next page when it comes into view.
Infinite scroll