A simple, tiny, library to automatically handle transient state, such as notifications, messages, or anything else that has a specific lifetime. An alternative to complex state, or messy passing down of state to emit and subscribe to events between children/siblings.
// Subscriber example
import useTransient from "@gilstroem/transient";
function Notifications() {
const notifications = useTransient();
return (
<ul>
{notifications.map((n) => (
<li key={n}>{n}</li>
))}
</ul>
);
}
...
// Insertion example
import { insert } from "@gilstroem/transient";
function Greet({ name }) {
return (
<button onClick={() => insert(`Welcome back, ${name}`)}>Greet me 👋</button>
);
}
npm install @gilstroem/transient
import useTransient from "@gilstroem/transient";
const data = useTransient(key);
key
: (optional) a unique key string used to denote the namespace of the state.
data
: an array of the data for the given key. Defaults to an empty array ([]
).
import { insert } from "@gilstroem/transient";
insert(`Hello, World!`, 6000, "notifications");
data
: a value of any type to be inserted and removed after alifetime
.lifetime
: (optional) a lifetime for the data in milliseconds (number
).key
: (optional) a key string denoting which namespace the date should be inserted into.
N/A
- Simple
- Namespaced
- Lifetimes
- Dependent Fetching
- Notifications use-case example (complex data)
- Typescript example
import useTransient from "@gilstroem/transient";
function Notifications() {
const notifications = useTransient();
return (
<ul>
{notifications.map((n) => (
<li key={n}>{n}</li>
))}
</ul>
);
}
...
import { insert } from "@gilstroem/transient";
function Greet({ name }) {
return (
<button onClick={() => insert(`Welcome back, ${name}`)}>Greet me 👋</button>
);
}
import useTransient from "@gilstroem/transient";
function Notifications() {
const notifications = useTransient("notifications");
const alerts = useTransient("alerts");
return (
<>
<h2>Notifications</h2>
<ul>
{notifications.map((n) => (
<li key={n}>{n}</li>
))}
</ul>
<h2>Alerts</h2>
<ul>
{alerts.map((a) => (
<li key={a}>{a}</li>
))}
</ul>
</>
);
}
...
import { insert } from "@gilstroem/transient";
function Greet({ name }) {
return (
<>
<button
onClick={() => insert(`Welcome back, ${name}`, null, "notifications")}
>
Greet me 👋
</button>
<button
onClick={() => insert(`Look behind you, ${name}`, null, "alerts")}
>
Warn me 🚨
</button>
</>
);
}
import { insert } from "@gilstroem/transient";
...
insert(`I am here for 5 seconds, the default lifetime`);
...
insert(`I will be gone in a second 👋`, 1000);
...
insert(`I will stick around for a minute 🐒`, 60000);
import useTransient from "@gilstroem/transient";
function Notifications() {
const notifications = useTransient("notifications");
return (
<ul>
{notifications.map(({ text, type }) => (
<li className={`notification type-${type}`} key={text}>
{text}
</li>
))}
</ul>
);
}
// ...
import { insert } from "@gilstroem/transient";
function CreateTodo() {
//... form state logic
const handleSubmit = () => {
try {
// ... submit logic
insert(
{ text: `Your todo was saved!`, type: "positive" },
4000,
"notifications"
);
} catch (err) {
insert(
{
text: `Your todo could not be saved, try again later!`,
type: "warning",
},
6000,
"notifications"
);
}
};
return (
// ... render a form
<button onClick={handleSubmit}>Save new todo</button>
);
}
import useTransient from "@gilstroem/transient";
export enum NotificationType {
NORMAL,
WARNING,
ALERT,
}
export interface Notification {
text: string,
type: NotificationType,
id: string
}
const Notifications: FunctionComponent = () => {
const notifications: Notification[] = useTransient<Notification>("notifications");
return (
<ul>
{notifications.map(({ text, type, id }) => (
<li className={`notification type-${type}`} key={id}>
{text}
</li>
))}
</ul>
);
}
// ...
import { insert } from "@gilstroem/transient";
import { v4 as uuid } from "uuid";
import { Notification, NotificationType } from "../path-to-notifications-component"
const CreateTodo: FunctionComponent = () => {
//... form state logic
const handleSubmit = () => {
try {
// ... submit logic
insert<Notification>(
{
text: `Your todo was saved! 👍`,
type: NotificationType.NORMAL,
id: uuid
},
4000,
"notifications"
);
} catch (err) {
insert<Notification>(
{
text: `Your todo could not be saved 👎 try again later!`,
type: NotificationType.ERROR,
id: uuid
},
6000,
"notifications"
);
}
};
return (
// ... render a form
<button onClick={handleSubmit}>Save new todo</button>
);
}
- Nikolaj Alexander Gilstroem (@gilstroem) – gilstroem.com
The MIT License.