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 onMutate
、onError
和 onSettled
起作用。这看起来像这样:
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 },
])
})
)
...
}
我一直在为我的应用程序使用 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 onMutate
、onError
和 onSettled
起作用。这看起来像这样:
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 },
])
})
)
...
}