export default function useOptimisticUpdates(action) { // old (to pass to other hooks) // update: character, list, options // delete: character, list, options // create: list, options // temp (update until settled) // create: character, list // new (to update) // update: character, list, options // delete: list, options // create: options // error (to rollback) // update: character, list, options // delete: character, list, options // create: list, options // success (to re-update with correct id) // create: character, list // onMutate // getOld // create new // update caches // cancel queries // return old and new for hooks // onSettled // invalidate list, options queries // if newCharacter || delete: invalidate character query // onError // if newList: rollback list, options // if newCharacter: rollback character // onSuccess // if create: reupdate list function getOld(id = null) { // save current for rollback const oldList = queryCache.getQueryData(characterListQuery.key) const oldOptions = queryCache.getQueryData(characterOptionsQuery.key) if (id) { const index = _findIndex(oldList, { id }) if (index >= 0) { const oldCharacter = oldList[index] return { oldCharacter, oldList, oldOptions } } else { return { oldList, oldOptions } } } function onSettled({ newCharacter }) { if (newCharacter) { queryCache.invalidateQueries({ key: characterListQuery.key }) queryCache.invalidateQueries({ key: characterByIdQuery(id).key }) } } function onError({ oldCharacter, oldCharacterList, oldOptions, newCharacterList }) { // before applying the rollback, check if the values in the cache are the same // in case the cache was updated by another mutation or query if (newCharacterList === queryCache.getQueryData(characterListQuery.key)) { queryCache.setQueryData(characterListQuery.key, oldCharacterList) queryCache.setQueryData(characterOptionsQuery.key, oldOptions) queryCache.setQueryData(characterByIdQuery(id).key, oldCharacter) } } function onSuccess() { // only create } }