在使用 RTK 查询时,第一个请求不会发送到数据库

the first request doesn't send to the database in working with RTK query

在我的项目中,我想增加和减少所列食物的数量。但在第一个请求中按下“更多”按钮后,数据库中的任何内容都不会改变,但在第二个请求中再次按下后,只需增加一次(刷新页面后你就会明白)。其实我不知道为什么第一个请求不算数。

演示:https://laughing-jang-201dc1.netlify.app/ .

Github : https://github.com/alibidjandy/burger

这是主要的 RTK 查询配置:

https://github.com/alibidjandy/burger/blob/main/src/Api/apiSlice.ts

import { current } from "@reduxjs/toolkit";
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
import {
  AllBurgerType,
  BurgerType,
  IngredientsType,
} from "../components/Layouts/burger/burgerSlice/burgerSlice";

export const burgerApi = createApi({
  reducerPath: "burgerApi",
  tagTypes: ["Ingredients"],
  baseQuery: fetchBaseQuery({
    baseUrl:
      "https://burger-order-brown-default-rtdb.europe-west1.firebasedatabase.app",
  }),
  endpoints: (builder) => ({
    getIngredients: builder.query<BurgerType, undefined>({
      // query: () => `/.json`,
      query: () => {
        return { url: "/.json", method: "GET" };
      },
      providesTags: ["Ingredients"],
    }),
    editIngredients: builder.mutation({
      query: (initialIngredients) => {
        return { url: "/.json", method: "PATCH", body: initialIngredients };
      },
      invalidatesTags: ["Ingredients"],
    }),
    increase: builder.mutation({
      query: ({ ing }) => {
        return {
          url: `/ingredients/${ing.id}/.json`,
          method: "PATCH",
          body: ing,
        };
      },
      async onQueryStarted({ ing }, { dispatch, queryFulfilled }) {
        const patchResult = dispatch(
          burgerApi.util.updateQueryData(
            "getIngredients",
            undefined,
            (draft) => {
              console.log("increase");
              // debugger;
              const ingredient = draft.ingredients.find(
                (ingredient) => ingredient.title === ing.title
              );
              if (ingredient) {
                console.log(current(ingredient));
                ingredient.Qty!++;
              }
            }
          )
        );
        try {
          await queryFulfilled;
        } catch {
          console.log("crashed");
          patchResult.undo();
        }
      },
    }),
    decrease: builder.mutation({
      query: ({ ing, indexIng }) => {
        return {
          url: `/ingredients/${indexIng}/.json`,
          method: "POST",
          body: ing,
        };
      },
      async onQueryStarted({ ing, indexIng }, { dispatch, queryFulfilled }) {
        const patchResult = dispatch(
          burgerApi.util.updateQueryData(
            "getIngredients",
            undefined,
            (draft) => {
              console.log("decrese");
              const ingredient = draft.ingredients[indexIng];
              if (ingredient.Qty !== undefined && ingredient.Qty > 0) {
                draft.totalCost = +(draft.totalCost -=
                  ingredient.cost!).toFixed(2);
                ingredient.Qty--;
              }
            }
          )
        );
        try {
          await queryFulfilled;
        } catch {
          patchResult.undo();
        }
      },
    }),
  }),
});
export const { editIngredients, getIngredients } = burgerApi.endpoints;
export const {
  useGetIngredientsQuery,
  useEditIngredientsMutation,
  useIncreaseMutation,
  useDecreaseMutation,
} = burgerApi;

等等...我正在重读您的代码。我认为您可能对 onQueryStartedupdateQueryData 的作用有非常错误的想法。 onQueryStarted 在 您的请求发送到服务器后 运行。 updateQueryData 仅在客户端更新您的数据。 因此,您将旧的客户端数据发送到服务器,然后在客户端更新它。 是的,难怪你的数据总是落后一步。 您需要首先将更新的数据发送到服务器。

你需要做类似

的事情
    increase: builder.mutation({
      query: ({ ing }) => {
        return {
          url: `/ingredients/${ing.id}/.json`,
          method: "PATCH",
          body: { ...ing, Qty: ing.Qty + 1 }
        };
      },

而且根本没有 onQueryStarted。 之后只需使用 invalidatesTags 从服务器重新获取正确的数据。

此外,正如我在您代码的其他地方偶然发现的那样:您正在使用 nanoid() 生成 id 并将其用作 key。永远不要那样做。 key 必须是稳定的,不能在每次渲染时都不同。这总是会导致 React 在每次渲染时销毁整个子组件 DOM 并丢弃所有子组件的整个本地状态。