Skip to content

Instantly share code, notes, and snippets.

@jacobstern
Last active December 3, 2018 21:57
Show Gist options
  • Save jacobstern/bb57841d6250a397d92cfbcd054629d1 to your computer and use it in GitHub Desktop.
Save jacobstern/bb57841d6250a397d92cfbcd054629d1 to your computer and use it in GitHub Desktop.
Redux scheme for `normalizr.js` and TypeScript
import { TOAST_NOTIFICATION_TRIGGERED } from '../../../constants/ActionTypes'
import { NotificationKind, ToastNotification } from './types'
import { normalizeToastNotification } from './schema'
export interface Action {
type: TOAST_NOTIFICATION_TRIGGERED
entities: object
id: ToastNotification['notificationId']
}
export const triggerToastNotification = (
kind: NotificationKind,
message: string,
timeoutLength: number = 3000
): Action => ({
type: TOAST_NOTIFICATION_TRIGGERED,
...normalizeToastNotification({
notificationId: String(Date.now()),
kind,
message,
timeoutLength,
})
})
import { normalizeToastNotification } from './schemas'
export const entitiesReducer = (state: object = {}, action: RootAction) => {
switch (action.type) {
case TOAST_NOTIFICATION_TRIGGERED:
return {
...state,
...action.entities,
}
default:
return state
}
import { schema, normalize } from 'normalizr'
import { ToastNotification } from './types'
// Would have a generic helper to define these
export interface NormalizeToastNotificationResult {
entities: object
result: ToastNotification['notificationId']
}
const toastNotificationSchema = new schema.Entity('toastNotifications', {
idAttribute: 'notificationId',
})
export const normalizeToastNotification = (
toastNotification: ToastNotification
) =>
normalize(
toastNotification,
toastNotificationSchema
) as NormalizeToastNotificationResult
export const denormalizeToastNotification = (
id: ToastNotification['notificationId'],
entities: object
) =>
denormalize(
id,
toastNotificationSchema,
entities
) as ToastNotification
import { denormalizeToastNotification } from './schemas'
export const selectToastNotifications = state =>
state.toastNotifications.map(id => denormalizeToastNotification(id, state.entities))
type ToastNotificationId = ToastNotification['notificationId']
export const toastNotificationsReducer = (
state: ToastNotificationId[] = [],
action: RootAction
) => {
switch (action.type) {
case TOAST_NOTIFICATION_TRIGGERED:
return [...state, action.id]
default:
return state
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment