Hooks

The value of using Hooks is being able to decouple React-y logic things, like state management and side effects, from the actual component that it is actually existing in

Hooks should be idempotent.

Hooks are functions, but they aren't pure functions.

  • this is why testing hooks is a little more involved— we can't just call the function and assert its output.

Each incovation of a hook is indepdendent. Therefore, if the hook manages state (e.g. via a useState or useContext hook), that state will be independent on each invocation of the hook.

  • Therefore, if we have a hook useStagingArea that manages state with useState and use it in 2 different components, the state of those two hooks will be independent
    • if we wish to share the state, then we must use something like a context.

Testing

If we can, it's generally not a bad idea to test hooks by simply testing the component that they are used in.

  • naturally, if the component tests pass, then the hook must be working properly.

Alternatively, we can use a setup helper that renders a dummy component (since a rule of hooks is that they must be called from within a component):

function setup(...args) {
  const returnVal = {}
  function TestComponent() {
    Object.assign(returnVal, useUndo(...args))
    return null
  }
  render(<TestComponent />)
  return returnVal
}

test('should ...', () => {
  const undoData = setup('one')

  // assert initial state
  expect(undoData.loading).toBe(false)

  // add second value (set is a function returned from the hook)
  act(() => {
    undoData.set('two')
  })

  // assert next state
  expect(undoData.loading).toBe(true)

Even more alternatively, we can use @testing-library/react-hooks, which gives us:

  • similar benefit to the setup function above
  • Utility to "rerender" the component that's rendering the hook (to test effect dependency changes for example)
  • Utility to "unmount" the component that's rendering the hook (to test effect cleanup functions for example)
  • Several async utilities to wait an unspecified amount of time (to test async logic)

Resources


Children
  1. useCallback
  2. useEffect
  3. useMemo
  4. useReducer

Backlinks