React-Query:编写多个useMutation自定义钩子的干净方法?

时间:2020-09-19 09:27:07

标签: reactjs react-query

我一直在使用useMutation()函数来完成我的应用程序的粗略任务,我觉得我在写很多重复的代码,起初我的代码就是这样

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))

我可以工作,但对我来说,它的代码看起来很混乱(再次重复很多代码)

"./mutate-api"

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;
 

问题:

有更好的方法吗?

1 个答案:

答案 0 :(得分:1)

减少重复代码的一种方法是创建一个 getOptions 函数,该函数返回 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 },
      ])
    })
  )

  ...
}