I see this everywhere in production codebases
Four separate states loading error data success gives you sixteen possible combinations Half of them are impossible like loading true and error not null at the same time But JavaScript doesnโt care about impossible states It just renders garbage on screen
Here is why this happens because developers think in booleans like is it loading is there error instead of thinking in states like what stage is the async process in right now
Here is how you fix it Use a discriminated union One object with a status field that can be idle loading success or error TypeScript then wonโt let you render data unless status is success Zero invalid states Zero bugs from impossible combinations
Here is when to use what For simple stuff like dark mode just use useState For async state without caching like form submit use discriminated union with useReducer For server state with caching and background refetch use React Query For complex related state like a filter panel use useReducer
React Query is great for server state But using it for a modal submit button is overkill Using seven separate useStates for a simple fetch is asking for bugs
Maturity is knowing the difference
What is your go to pattern for async state in React
Top comments (0)