Skip to content

Instantly share code, notes, and snippets.

@gabrieledarrigo
Created May 15, 2020 18:00
Show Gist options
  • Save gabrieledarrigo/91571b1c831c6e1a1db516a43a32409b to your computer and use it in GitHub Desktop.
Save gabrieledarrigo/91571b1c831c6e1a1db516a43a32409b to your computer and use it in GitHub Desktop.
A draft for a notifications hooks
import React, { useReducer } from 'react';
const uuid = () => Math.random();
export function reducer(state, action) {
switch (action.type) {
case 'show':
return [
action.notification,
...state,
];
case 'remove':
return state.filter((notification) => notification.id !== action.notification.id);
case 'clear':
return [];
default:
throw new Error();
}
}
export function useNotifications(initialState = []) {
const [notifications, dispatch] = useReducer(reducer, [
...initialState,
]);
function checkTTL(id, ttl) {
if (ttl !== 0) {
setTimeout(() => {
dispatch({
type: 'remove',
notification: {
id,
},
});
}, ttl);
}
}
function show(message, ttl) {
const id = uuid();
dispatch({
type: 'show',
notification: {
id,
message,
ttl,
},
});
checkTTL(id);
}
function remove(id) {
dispatch({
type: 'remove',
notification: {
id,
},
});
}
function clear() {
dispatch({
type: 'clear',
});
}
return {
notifications,
show,
remove,
clear,
};
}
export function Notifications() {
const { notifications, remove } = useNotifications([]);
return (
<div>
{notifications.map((notification) => (
<div key={notification.id}>
<button
type="button"
onClick={() => remove(notification.id)}
>
<span role="img" aria-label="Close">
</span>
</button>
<p>
{notification.message}
</p>
</div>
))}
</div>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment