useOnChange.ts 684 B

123456789101112131415161718192021222324252627
  1. import { useState } from 'react'
  2. function isDifferent(a: unknown, b: unknown): boolean {
  3. if (Array.isArray(a) && Array.isArray(b)) {
  4. return b.length !== a.length || a.some((v, i) => isDifferent(v, b[i]))
  5. }
  6. return a !== b
  7. }
  8. /**
  9. * @param value - state to watch
  10. * @param onChange - when the state changed
  11. * @param isUpdated - a function that determines if the state is updated
  12. */
  13. export function useOnChange<T>(
  14. value: T,
  15. onChange: (current: T, previous: T) => void,
  16. isUpdated: (prev: T, current: T) => boolean = isDifferent
  17. ): void {
  18. const [prev, setPrev] = useState<T>(value)
  19. if (isUpdated(prev, value)) {
  20. onChange(value, prev)
  21. setPrev(value)
  22. }
  23. }