useOptimisticUpdates.js 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. export default function useOptimisticUpdates(action) {
  2. // old (to pass to other hooks)
  3. // update: character, list, options
  4. // delete: character, list, options
  5. // create: list, options
  6. // temp (update until settled)
  7. // create: character, list
  8. // new (to update)
  9. // update: character, list, options
  10. // delete: list, options
  11. // create: options
  12. // error (to rollback)
  13. // update: character, list, options
  14. // delete: character, list, options
  15. // create: list, options
  16. // success (to re-update with correct id)
  17. // create: character, list
  18. // onMutate
  19. // getOld
  20. // create new
  21. // update caches
  22. // cancel queries
  23. // return old and new for hooks
  24. // onSettled
  25. // invalidate list, options queries
  26. // if newCharacter || delete: invalidate character query
  27. // onError
  28. // if newList: rollback list, options
  29. // if newCharacter: rollback character
  30. // onSuccess
  31. // if create: reupdate list
  32. function getOld(id = null) {
  33. // save current for rollback
  34. const oldList = queryCache.getQueryData(characterListQuery.key)
  35. const oldOptions = queryCache.getQueryData(characterOptionsQuery.key)
  36. if (id) {
  37. const index = _findIndex(oldList, { id })
  38. if (index >= 0) {
  39. const oldCharacter = oldList[index]
  40. return { oldCharacter, oldList, oldOptions }
  41. } else {
  42. return { oldList, oldOptions }
  43. }
  44. }
  45. function onSettled({ newCharacter }) {
  46. if (newCharacter) {
  47. queryCache.invalidateQueries({ key: characterListQuery.key })
  48. queryCache.invalidateQueries({ key: characterByIdQuery(id).key })
  49. }
  50. }
  51. function onError({ oldCharacter, oldCharacterList, oldOptions, newCharacterList }) {
  52. // before applying the rollback, check if the values in the cache are the same
  53. // in case the cache was updated by another mutation or query
  54. if (newCharacterList === queryCache.getQueryData(characterListQuery.key)) {
  55. queryCache.setQueryData(characterListQuery.key, oldCharacterList)
  56. queryCache.setQueryData(characterOptionsQuery.key, oldOptions)
  57. queryCache.setQueryData(characterByIdQuery(id).key, oldCharacter)
  58. }
  59. }
  60. function onSuccess() {
  61. // only create
  62. }
  63. }