React Query:编写多个 useMutation 自定义挂钩的简洁方法?

React Query: clean way of writing multiple useMutation custom hooks?

我一直在为我的应用程序使用 useMutation() 挂钩来完成 crud 任务,我觉得我在写很多重复的代码,最初我的代码是这样的:

const [createList] = useCreateList(reset, err => setError(err.message));
const [updateList] = useCreateList(reset, err => setError(err.message));
const [deleteList] = useCreateList(reset, err => setError(err.message));

复位函数是这样的:

const reset = () => {
    setQsButtonStatus(null); 
    setSelectedList(null);
    setTitleValue("");
}

我想要的结束代码是这样的:

const {createList, updateList, deleteList} = useListMutation(reset, err => setError(err.message))

我可以完成这项工作,但对我来说它的代码看起来很乱(又是很多重复的代码):

import * as List from "./list-api";

const useListMutation = (onSettled, onError) => {

    const [createList] = useMutation(List.createList, {
        onMutate: (listTitle) => {
            queryCache.cancelQueries("lists");
            const current = queryCache.getQueryData("lists");
            queryCache.setQueryData("lists", prev => [...prev, {title: listTitle, id: uuidv4()}])
            return () => queryCache.setQueryData("lists", current);
        },
        onError: (err, variables, rollback) => {rollback(); onError(err)},
        onSettled: () => {
            queryCache.invalidateQueries("lists");
            onSettled();
        }
    })

    const [updateList] = useMutation(List.updateList, {
        onMutate: ({id, titleValue}) => {
            queryCache.cancelQueries("lists");
            const current = queryCache.getQueryData("lists");
            queryCache.setQueryData("lists", prev => [
                ...prev.filter(list => list._id !== id),
                {_id: id, title: titleValue}
            ])
            return () => queryCache.setQueryData("lists", current);
        },
        onError: (err, variables, rollback) => {rollback(); onError(err)},
        onSettled: () => {
            queryCache.invalidateQueries("lists");
            onSettled();
        }
    })

    const [deleteList] = useMutation(List.deleteList, {
        onMutate: (id) => {
            queryCache.cancelQueries("lists");
            const current = queryCache.getQueryData("lists");
            queryCache.setQueryData("lists", prev => [
                ...prev.filter(list => list._id !== id),
            ])
            return () => queryCache.setQueryData("lists", current);
        },
        onError: (err, variables, rollback) => {rollback(); onError(err)},
        onSettled: () => {
            queryCache.invalidateQueries("lists");
            onSettled();
        }
    })


    return {createList, updateList, deleteList};

}

export default useListMutation; 

有更好的方法吗?

减少重复代码的一种方法是创建一个 getOptions 函数,其中 returns onMutateonErroronSettled 起作用。这看起来像这样:

const useListMutation = (onSettled, onError) => {
  const getOptions = (onMutate) => ({
    onMutate(data) {
      queryCache.cancelQueries("lists")
      const current = queryCache.getQueryData("lists")
      onMutate(data)
      return () => queryCache.setQueryData("lists", current)
    },
    onError(err, variables, rollback) {
      rollback()
      onError(err)
    },
    onSettled() {
      queryCache.invalidateQueries("lists")
      onSettled()
    },
  })

  const [createList] = useMutation(
    List.createList,
    getOptions((listTitle) => {
      queryCache.setQueryData("lists", (prev) => [
        ...prev,
        { title: listTitle, id: uuidv4() },
      ])
    })
  )

  const [updateList] = useMutation(
    List.updateList,
    getOptions(({ id, titleValue }) => {
      queryCache.setQueryData("lists", (prev) => [
        ...prev.filter((list) => list._id !== id),
        { _id: id, title: titleValue },
      ])
    })
  )

  ...
}