Skip to content

Instantly share code, notes, and snippets.

@krivaten
Last active July 19, 2025 18:10
Show Gist options
  • Save krivaten/2b71c39e15bd748ba6b6e86de0c68ab2 to your computer and use it in GitHub Desktop.
Save krivaten/2b71c39e15bd748ba6b6e86de0c68ab2 to your computer and use it in GitHub Desktop.
Better State Example
/**
* An enum representing the possible states of UI features
*
* These states help design consistent user experiences across different
* scenarios like loading, empty states, errors, and varying data quantities.
*/
export enum State {
/**
* The starting state before any user interaction or data loading.
* Example: A search page before the user has entered a query.
*/
INITIAL = "INITIAL",
/**
* An asynchronous operation is in progress (loading, saving, etc.).
* Example: Showing a spinner while fetching search results.
*/
PENDING = "PENDING",
/**
* An asynchronous operation has completed successfully.
* Note: This typically transitions to NONE, ONE, SOME, or MANY based on results.
*/
DONE = "DONE",
/**
* No data/items are available to display.
* Example: "No search results found" or empty shopping cart.
*/
NONE = "NONE",
/**
* Exactly one item is present.
* Example: Single search result or one item in cart.
*/
ONE = "ONE",
/**
* A small number of items are present (typically 2-10).
* UI consideration: Simple list layout, no pagination needed.
*/
SOME = "SOME",
/**
* A large number of items are present (typically 10+).
* UI consideration: Requires pagination, virtualization, or load-more patterns.
*/
MANY = "MANY",
/**
* An error has occurred (validation, network, server, etc.).
* Example: Form validation errors, failed API requests.
*/
ERROR = "ERROR",
/**
* An operation completed successfully with user feedback needed.
* Example: "Profile saved successfully" confirmation message.
*/
SUCCESS = "SUCCESS",
}
useEffect(() => {
(async () => {
try {
const { profiles } = await apiRequest(`/profiles`);
setProfiles(profiles);
const profilesCount = profiles.length || 0;
if (profilesCount === 0)
setState(State.NONE);
else if (profilesCount === 1)
setState(State.ONE);
else if (profilesCount > 1 && profilesCount <= 5)
setState(State.SOME);
else
setState(State.MANY);
} catch (error) {
setState(State.ERROR);
console.error("Failed to fetch profiles:", error);
}
})();
}, []);
<div>
<PageSubtitle>Profile</PageSubtitle>
{state === State.LOADING && <Spinner />}
{state === State.NONE && (
<>
<Alert>
<Info className="h-4 w-4" />
<AlertTitle>No profiles</AlertTitle>
<AlertDescription>
You don't have any profiles. Let's create one!
</AlertDescription>
</Alert>
<ProfileForm />
</>
)}
{state === State.ONE && (
<>
<ProfileForm profile={profiles[0]} />
<Button onClick={this.createNewProfile}>
Create New Profile
</Button>
</>
)}
{(state === State.SOME || state === State.MANY) && (
<ul className="divide-y divide-gray-100">
{profiles.map((profile) => (
<li key={profile?.id}>
<div className="font-semibold">
{profile.first_name} {profile.last_name}
{profile.display_name
? ` (${profile.display_name})`
: undefined}
</div>
<div className="text-xs">
{profile.created_at
? new Date(profile.created_at).toDateString()
: undefined}
</div>
</li>
))}
</ul>
)}
{state === State.ERROR && (
<>
<Alert>
<Info className="h-4 w-4" />
<AlertTitle>Error</AlertTitle>
<AlertDescription>
There was an issue fetching your profiles. Please try again.
</AlertDescription>
</Alert>
</>
)}
</div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment