syntax-sugar
v3.0.0
Published
Syntax Sugar for React - A collection of utility components and hooks to simplify React development
Downloads
54
Maintainers
Readme
syntax-sugar
Syntax Sugar for React — a small collection of utility components and hooks to simplify conditional rendering, list rendering, and data fetching.
Installation
npm install syntax-sugarreact, react-dom, and axios are peer dependencies, so make sure they are installed in your project.
Components
If
Conditionally renders content based on condition.
When condition is truthy it renders the truthy branch; otherwise it renders the else branch (or null when omitted). The non-rendered branch is never evaluated when the truthy branch is a render function, so you can safely access properties narrowed from condition without ! or optional chaining.
Props
condition: The value evaluated as the condition. Truthy renders the truthy branch.else(optional): Rendered whenconditionis falsy. Defaults tonull.children: The truthy branch. AReactNodeor a render function(value) => ReactNodethat receivesconditionnarrowed to its non-falsy type. Cannot be combined withthen.then: An alternative tochildrenfor the truthy branch, useful with the self-closing form. Same shape aschildren. Cannot be combined withchildren.
Usage
import { If } from 'syntax-sugar';
const MyComponent = ({ isLoggedIn }) => {
return (
<If condition={isLoggedIn} else={<h1>Please login.</h1>}>
<h1>Welcome back!</h1>
</If>
);
};Using then and else in the self-closing form:
<If condition={isLoggedIn} then={<h1>Welcome back!</h1>} else={<h1>Please login.</h1>} />With type narrowing (the render function only runs when condition is truthy):
<If condition={user} else={<Loading />}>
{(user) => <span>{user.name}</span>}
</If>Each
Renders a list of items using a render function.
Props
of: The items to render. Accepts mutable orreadonlyarrays.renderAs: Render function for each item. Receives(item, index, array), matchingArray.prototype.mapsemantics.getKey(optional): Returns a stable key for each item,(item, index) => string | number. Strongly recommended when items can be reordered, inserted, or removed. When omitted, the item index is used as the key (and in development a one-time warning is logged for arrays with more than one item).fallback(optional): Rendered whenofis empty. Defaults tonull.
Usage
import { Each } from 'syntax-sugar';
const MyComponent = () => {
const fruits = [
{ id: 1, name: 'apple' },
{ id: 2, name: 'banana' },
{ id: 3, name: 'orange' },
];
return (
<ul>
<Each
of={fruits}
getKey={(fruit) => fruit.id}
renderAs={(fruit) => <li>{fruit.name}</li>}
fallback={<li>No fruits</li>}
/>
</ul>
);
};Hooks
useFetch
A lightweight Axios wrapper hook with proper cancellation, mount safety, and concurrency handling.
The caller passes a factory (signal: AbortSignal) => Promise<AxiosResponse<T>> so the hook owns the AbortController and can wire cancellation into Axios. The signal must be forwarded to Axios for cancellation to take effect.
Returns
makeRequest(factory): Fires a request and resolves to a tuple[data, null] | [null, error]. It never throws. Calling it while a previous request is in flight automatically aborts the previous one.isPending:truewhile a request from this hook is in flight.error: The lastErrorfrom a non-canceled request, ornull. Cleared at the start of every request. Cancellations do not populate this state.cancel(): Aborts the in-flight request, if any. Safe to call when idle.
Exported types: FetchFactory<T>, FetchResult<T>.
Usage
import { useFetch } from 'syntax-sugar';
import { useEffect, useState } from 'react';
import axios from 'axios';
const MyComponent = () => {
const { makeRequest, isPending, error } = useFetch();
const [users, setUsers] = useState([]);
useEffect(() => {
void makeRequest((signal) =>
axios.get('https://api.example.com/users', { signal })
).then(([data, err]) => {
if (data) setUsers(data);
});
}, [makeRequest]);
if (isPending) return <p>Loading...</p>;
if (error) return <p>Error: {error.message}</p>;
return (
<ul>
{users.map((user) => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
};