Skip to content

Instantly share code, notes, and snippets.

@itsMapleLeaf
Last active September 28, 2020 17:08
Show Gist options
  • Select an option

  • Save itsMapleLeaf/e8f59b983324ff09b14dca6dd6fb9b8f to your computer and use it in GitHub Desktop.

Select an option

Save itsMapleLeaf/e8f59b983324ff09b14dca6dd6fb9b8f to your computer and use it in GitHub Desktop.
useDict
import { useCallback, useState } from "react"
const emptyDict = {}
export default function useDict<T>(
initialItems: Record<string, T | undefined> = emptyDict,
) {
const [items, setItems] = useState(initialItems)
const add = useCallback(
(key: string, item: T) => setItems((items) => ({ ...items, [key]: item })),
[],
)
const remove = useCallback(
(key: string) => setItems((items) => ({ ...items, [key]: undefined })),
[],
)
const update = useCallback(
(key: string, getNew: (current: T | undefined) => T) => {
setItems((items) => ({
...items,
[key]: getNew(items[key]),
}))
},
[],
)
const updateExisting = useCallback(
(key: string, getNew: (current: T) => T) => {
setItems((items) => {
const current = items[key]
return { ...items, [key]: current && getNew(current) }
})
},
[],
)
const updateOrCreate = useCallback(
(
key: string,
getFromExisting: (current: T) => T,
getNew: (key: string) => T,
) => {
setItems((items) => {
const current = items[key] ?? getNew(key)
return { ...items, [key]: getFromExisting(current) }
})
},
[],
)
return { items, add, remove, update, updateExisting, updateOrCreate }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment