React 查询突变打字稿

use*_*366 12 reactjs react-query

我只是在玩反应查询

带打字稿

我的意思是我做了我的第一次尝试

这是正确的方法吗?

const useCreateTodo = () => {
  const queryClient = useQueryClient();
  return useMutation(
    (todo: TodoDto) => axios.post(`${URL}/todos`, todo).then((res) => res.data),
    {
      onMutate: async (newTodo: TodoDto) => {
        // Cancel any outgoing refetches (so they don't overwrite our optimistic update)
        await queryClient.cancelQueries("todos");

        // Snapshot the previous value
        const previousTodos = queryClient.getQueryData("todos");

        // Optimistically update to the new value
        queryClient.setQueryData<TodoDto[] | undefined>("todos", (old) =>
          old ? [...old, newTodo] : old
        );

        // Return a context object with the snapshotted value
        return { previousTodos };
      },
      // If the mutation fails, use the context returned from onMutate to roll back
      onError: (
        err,
        newTodo,
        context:
          | {
              previousTodos: unknown;
            }
          | undefined
      ) => {
        queryClient.setQueryData(
          "todos",
          context ? context.previousTodos : context
        );
      },
      // Always refetch after error or success:
      onSettled: () => {
        queryClient.invalidateQueries("todos");
      },
    }
  );
};
Run Code Online (Sandbox Code Playgroud)

TkD*_*odo 12

乐观更新对于类型推断来说有点棘手。现在文档中有一个针对这种具体情况的示例。

从那个例子来看:

const addTodoMutation = useMutation(
    newTodo => axios.post('/api/data', { text: newTodo }),
    {
      // When mutate is called:
      onMutate: async (newTodo: string) => {
        setText('')
        // Cancel any outgoing refetches (so they don't overwrite our optimistic update)
        await queryClient.cancelQueries('todos')

        // Snapshot the previous value
        const previousTodos = queryClient.getQueryData<Todos>('todos')

        // Optimistically update to the new value
        if (previousTodos) {
          queryClient.setQueryData<Todos>('todos', {
            ...previousTodos,
            items: [
              ...previousTodos.items,
              { id: Math.random().toString(), text: newTodo },
            ],
          })
        }

        return { previousTodos }
      },
      // If the mutation fails, use the context returned from onMutate to roll back
      onError: (err, variables, context) => {
        if (context?.previousTodos) {
          queryClient.setQueryData<Todos>('todos', context.previousTodos)
        }
      },
      // Always refetch after error or success:
      onSettled: () => {
        queryClient.invalidateQueries('todos')
      },
    }
  )
Run Code Online (Sandbox Code Playgroud)

一些解释:

  • 基本上,您只想在 上设置类型定义onMutate,以便类型推断适用于mutateFn( newTodois inferred) 以及 中的上下文onError
  • 添加泛型以便getQueryData键入previousTodos。但你不需要联合undefined- React-query 会为你做到这一点。
  • 的功能更新程序setQueryData很棘手,因为它要求您返回一个数组,但old可能是未定义的。我更喜欢使用previousTodos返回的getQueryData

  • 当然是。`useQueryClient` 只是反应上下文:) (2认同)