Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
function NotificationsHeader({ fetchNotifications, subscribeNotifications }) {
const [notifications, setNotifications] = useState([])
useEffect(() => {
// fetch initial notifications
fetchNotifications().then(notifications => {
setNotifications(notifications)
})
// subscribe to new notifications
const unsubscribe = subscribeNotifications(newNotification => {
// Important: use callback in `setNotification` to get the current state,
// otherwise you would need to re-subscribe when `notifications` variables changes
// Bad - content of notifications variable doesn't change:
// setNotifications([...notifications, newNotifications])
// Good - `notifications` are always the current state
setNotifications(notifications => [...notifications, newNotification])
})
// unsubscribe on unmount
return () => unsubscribe()
}, []) // run effect only on mount
// memoize callback
const cleanNotifications = useCallback(() => setNotifications([]), [])
return <NotificationList onClose={cleanNotifications} notifications={notifications} />
}
// NotificationList only renders data, when it's open.
function NotificationList({ onClose, notifications }) {
const [isOpen, setOpen] = setState(false)
return (
<>
<button onClick={() => setOpen(true)}>Notifications ({notifications.length})</button>
{isOpen && <ul>{notifications.map(...)}</ul>
</>
)
}
function useNotifications({ fetchNotifications, subscribeNotifications }) {
const [notifications, setNotifications] = useState([])
useEffect(() => {
// fetch initial notifications
fetchNotifications().then(notifications => {
setNotifications(notifications)
})
// subscribe to new notifications
const unsubscribe = subscribeNotifications(newNotification => {
// Important: use callback in `setNotification` to get the current state,
// otherwise you would need to re-subscribe when `notifications` variables changes
// Bad - content of notifications variable doesn't change:
// setNotifications([...notifications, newNotifications])
// Good - `notifications` are always the current state
setNotifications(notifications => [...notifications, newNotification])
})
// unsubscribe on unmount
return () => unsubscribe()
}, []) // run effect only on mount
// memoize callback
const cleanNotifications = useCallback(() => setNotifications([]), [])
return { notifications, cleanNotifications }
}
// NotificationList only renders data, when it's open, but keeps receiving them.
function NotificationList({ fetchNotifications, subscribeNotifications }) {
const [isOpen, setOpen] = setState(false)
const { notifications, cleanNotifications } = useNotifications({ fetchNotifications, subscribeNotifications })
return (
<>
<button onClick={() => setOpen(true)}>Notifications ({notifications.length})</button>
{isOpen && <ul>{notifications.map(...)}</ul>
</>
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.