0.4.0 • Published 5 years ago

@andrewmat/hooks v0.4.0

Weekly downloads
-
License
MIT
Repository
github
Last release
5 years ago

Andrewmat/hooks

I've developed some custom hooks making the SWBD project, and now I'm sharing it. Just that.

Usage

Add it to your project

npm install @andrewmat/hooks
yarn add @andrewmat/hooks

Starting using it

import { useCache, CacheProvider } from '@andrewmat/hooks'
import { useCounter } from '@andrewmat/hooks'
import { useDocumentTitle } from '@andrewmat/hooks'
import { useIterator } from '@andrewmat/hooks'
import { useToggle } from '@andrewmat/hooks'

So... where are they?

Inside the /src/hooks there are multiple hooks that I developed. I'm avoiding using external package dependencies, and focusing only on the original React resources for now

useToggle

Standalone hook

Identity:

const [value, toggle] = useToggle([initialValue = false, toggleValue = true])

It stores one of two options, and returns the current option and a function that changes to the other option. As default, it simply changes between booleans, with false as initial value.

function MyComponent() {
  const [myBool, toggleMyBool] = useToggle()

  // button label is false/true
  return (
    <button onClick={toggleMyBool}>
      {myBool}
    </button>
  )
}

It also can receive a initial boolean value

function MyComponent() {
  const initialValue = true
  const [myBool, toggleMyBool] = useToggle(initialValue)

  // button label is true/false
  return (
    <button onClick={toggleMyBool}>
      {myBool}
    </button>
  )
}

It also can receive an array of two elements, and if so, it toggles between then. The index 0 will be the initial value in this case

function MyComponent() {
  const [theme, toggleTheme] = useToggle(['blue', 'pink'])

  return (
    <div>
      This is the {theme} theme!
      <button onClick={toggleTheme} className={`${theme}-theme`}>
        Toggle
      </button>
    </div>
  )
}

useCounter

Standalone hook

Identity:

const [value, increment] = useCounter(initialValue = 0)

It returns the current value, and an increment function, in array form

function MyComponent() {
  const [value, increment] = useCounter()
  return <button onClick={increment}>value</button>
}

useDocumentTitle

Standalone hook

Identity:

useDocumentTitle(title)

It receives an title to apply to the document. It also returns to the previous title when the component unmounts

function MyComponent() {
  useDocumentTitle('Example Title')
  return <div />
}

useIterator

Standalone hook

Identity:

const controller = useIterator(list, loop = false, startIndex = 0)
// controller: { item, index, next, previous, hasNext, hasPrevious }

It receives an array, and returns an controller to iterate in this array

function MyComponent() {
  const myList = ['Alice', 'Ben', 'Charles']
  const iterator = useIterator(list)
  return (
    <div>
      <button onClick={iterator.previous}>Previous</button>
      {iterator.item}
      <button onClick={iterator.next}>Next</button>
    </div>
  )
}

useIterator also can received two more arguments

// loop: Whether or not should the list loop. Defaults to false
// startIndex: What index should be the initial item. Defaults to 0
useIterator(list, loop, startIndex)

The controller returned by this hook is composed of the following attributes:

const iterator = useIterator(list)

// current item being iterated
iterator.item

// index of the current item
iterator.index

// function to iterate to the next item on the list
// returns the controller so it can be chained
const nextIterator = iterator.next()

// function to iterate to the previous item on the list
// returns the controller so it can be chained
const previousIterator = iterator.previous()

// boolean that detects if it has a next item on the list
// it also accounts if the iterator loops
iterator.hasNext

// boolean that detects if it has a previous item on the list
// it also accounts if the iterator loops
iterator.hasPrevious

useCache

const cacheFetch = useCache(async function () {})

A hook to use cache to store resolutions of async functions. It uses the CacheProvider (inside /src/components) that creates an context used for caching resources.

It receives an async function, and it returns an async function that mimics the given function, using caching resources whenever possible

function myFetch(id) {
  returns fetch(`${apiUrl}/${id}`)
}

function MyComponent() {
  const myCachedFetch = useCache(myFetch)

  return (
    <MyAnotherComponent onChange={myCachedFetch} />
  )
}

// useCache should be used alongside CacheProvider
function App() {
  return (
    <CacheProvider>
      <MyComponent/>
    </CacheProvider>
  )
}

It receives a namespace as second argument. If not set, it uses __root as default, althought I recommend to always use it to avoid name clashes between diferent contexts

function MyComponent() {
  const myCachedFetch = useCache(myFetch, 'myNamespace')

  return (
    <MyAnotherComponent onChange={myCachedFetch} />
  )
}

It also receives a config object as third parameter. The config object is as follows:

const cacheConfig = {
  // optional function that generates key
  // It receives an array of parameters and must return an string
  keyGenerator,

  // optional key of cache entry
  // It overwrites the keyGenerator function
  key,

  // optional key to limit entries inside the namespace
  limit
}
useCache(myFetch, 'myNamespace', cacheConfig)

The returned function also has a new attribute: clearCache, a function that removes all the entries from the cache of the given namespace

function MyComponent({ data }) {
  const cachedFetch = useCache(myFetch, { namespace: 'my-fetch' })

  return (
    <div>
      <button onClick={() => cachedFetch(data)}>Fetch data<button>
      <button onClick={cachedFetch.clearCache}>Reset cache<button>
    </div>
  )
}
0.4.0

5 years ago

0.3.0

5 years ago

0.2.4

5 years ago

0.2.3

5 years ago

0.2.2

5 years ago

0.2.1

5 years ago

0.2.0

5 years ago

0.1.2

5 years ago

0.1.0

5 years ago