0.0.13-fixlogs.2 • Published 1 year ago

@rcharmeyer/react-utils v0.0.13-fixlogs.2

Weekly downloads
-
License
MIT
Repository
github
Last release
1 year ago

react-utils

My library of React utilities.

Hooks

Scopes & Hoisting State

Using createStore

const AccordionScope = createScope ()

const openIdStore = createStore (() => {
  const [ openId, setOpenId ] = useState (null)
  return { openId, setOpenId }
}, [ AccordionScope ])

function AccordionItem ({ id, children }) {
  const { openId, setOpenId } = useStore (openIdStore)
  const open = openId === id
  const toggleOpen = useEvent (() => setOpenId (open ? null : id))

  return (
    <Expandable open={open} onToggle={toggleOpen}>
      {children}
    </Expandable>
  )
}

Adding createStoreFamily

const AccordionScope = createScope ()

const openIdStore = createStore (() => {
  const [ openId, setOpenId ] = useState (null)
  return { openId, setOpenId }
}, [ AccordionScope ])

const openStoreBy = createStoreFamily ((id) => {
  const { openId, setOpenId } = useStore (openIdStore)
  const open = openId === id
  const toggleOpen = useEvent (() => setOpenId (open ? null : id))
  return { open, toggleOpen }
}, [ AccordionScope ])

function AccordionItem ({ id, children }) {
  const { open, toggleOpen } = useStore (openStoreBy (id))
  return (
    <Expandable open={open} onToggle={toggleOpen}>
      {children}
    </Expandable>
  )
}

Using hoist instead of create

const AccordionScope = createScope ()

const useOpenIdState = hoist (() => {
  const [ openId, setOpenId ] = useState (null)
  return { openId, setOpenId }
}, [ AccordionScope ])

const useOpenToggleBy = hoist ((id) => {
  const { openId, setOpenId } = useStore (openIdStore)
  const open = openId === id
  const toggleOpen = useEvent (() => setOpenId (open ? null : id))
  return { open, toggleOpen }
}, [ AccordionScope ])

function AccordionItem ({ id, children }) {
  const { open, toggleOpen } = useOpenToggleBy (id)
  return (
    <Expandable open={open} onToggle={toggleOpen}>
      {children}
    </Expandable>
  )
}

Utilities

useEvent

Based on this React RFC of the same name.

This hook is a lot like useCallback but it requires no deps because the reference is always stable and always represents the latest callback. However, unlike useCallback it does not support returning values or async functions.

function Expandable ({ children }) {
  const [ active, setActive ] = useState (false)

  const toggleActive = useEvent (() => {
    setActive (!active)
  })

  // Button never re-renders, not possible with useCallback
  return <>
    <Button onClick={toggleActive}>
    {active && <div>{children}</div>}
  </>
}

useStruct

// with useStruct
function useTuple (a, b) {
  return useStruct ([ a, b ])
}

// without
function useTuple (a, b) {
  return useMemo (() => {
    return [a, b] as const
  }, [a, b])
}

useMemoShallow

useMemo except it will also check for shallow equality of the return value.

type Item = {
  id: string,
  tags: string[],
}

function useFilteredItems (items: Item[], tag: string) {
  return useMemoShallow (() => {
    return items.filter (item => item.tags.includes (tag))
  }, [ items, tag ])
}
0.0.12

1 year ago

0.0.11

1 year ago

0.0.10

1 year ago

0.0.9

1 year ago

0.0.8

1 year ago

0.0.7

1 year ago

0.0.6

1 year ago

0.0.5

1 year ago

0.0.4

1 year ago

0.0.3

1 year ago

0.0.2

1 year ago

0.0.1

1 year ago