Skip to content

Instantly share code, notes, and snippets.

@Haraldson
Created March 20, 2020 15:45
Show Gist options
  • Save Haraldson/c682dd50be9939f90baa24a4445e10f3 to your computer and use it in GitHub Desktop.
Save Haraldson/c682dd50be9939f90baa24a4445e10f3 to your computer and use it in GitHub Desktop.
const People = () => {
const peopleContext = useContext(PeopleContext)
const [people, sort, setSortField] = useSort({
items: peopleContext.people ?? [],
fields: {
name: {
method: 'compare',
getValue: ({ firstName, lastName }) => `${lastName} ${firstName}`,
order: 'asc'
},
registered: {
method: 'simple',
getValue: ({ registeredAt }) => parseISO(registeredAt).getTime(),
order: 'desc'
}
},
defaultField: 'name',
storageKey: 'list:people:sort',
makeSalt: items => items.map(({ id }) => id).join()
})
return (
<>
{people.map(person => (
...
))}
</>
)
}
import { useState, useEffect } from 'react'
import { useIntl } from 'react-intl'
import { useStorage } from 'hooks/storage'
export const useSort = ({ items, fields, defaultField, storageKey, makeSalt }) => {
items = [...items]
const salt = makeSalt(items)
const { locale } = useIntl()
const [sortedItems, setSortedItems] = useState([])
const defaultSort = {
by: defaultField,
order: fields[defaultField].order
}
const [sort, setSort] = useStorage(storageKey, defaultSort)
if(!(sort.by in fields)) {
setSort(defaultSort)
}
const setSortField = field => setSort({
by: field,
order: (sort.by === field) ?
(sort.order === 'asc' ? 'desc' : 'asc') :
fields[field].order
})
useEffect(() => {
const { getValue, method } = fields[sort.by]
setSortedItems(items.sort((one, two) => {
const orderModifier = sort.order === 'desc' ? -1 : 1
one = getValue(one)
if(!one) {
return 1 * orderModifier
}
two = getValue(two)
if(!two) {
return -1 * orderModifier
}
if(one === two) {
return 0
}
let comparison = 0
if(method === 'simple') {
comparison = one - two
}
if(method === 'compare') {
comparison = one.localeCompare(two, locale, { sensitivity: 'base' })
}
return comparison * orderModifier
}))
}, [sort.by, sort.order, locale, salt])
return [sortedItems, sort, setSortField]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment