Use Immer with Recoil

Viewed 8

I'm hoping to get the performace benefits of Immer and the state management of Recoil but don't know how to synchronize the state from useImmer with that of useRecoilState.

1 Answers

The core of immer is the produce function, which applies changes performantly.

To use it with recoil simply use produce inside setState, instead of useImmer.

import { RecoilState, useRecoilState } from 'recoil'
import { produce, Draft } from 'immer'

type DraftFunction<T> = (draft: Draft<T>) => void

export const useRecoilImmerState = <T>(atom: RecoilState<T>) => {
  const [state, setState] = useRecoilState(atom)
  return [
  state,
  useCallback((valOrUpdater: T | DraftFunction<T>) => 
  setState(
    typeof valOrUpdater === 'function'
      ? produce(valOrUpdater as DraftFunction<T>)
      : valOrUpdater as T
    ), [setRecoilState])
  ] as const
}

This approach is very similar to how useImmer works.

Related