Как сделать почтовый запрос в Next 13 с помощью каталога приложений и RTK Query

Как я могу сделать POST-запрос к своему бэкэнду, используя RTK Query в NextJS 13, из новой папки API?

Как правильно инициировать запрос? Я пробовал следующие 2 способа отправки, и ни один из них не работал:

//first try
const dispatch = useDispatch<AppDispatch>();
dispatch(addMemoria.initiate({firstName, lastName, birthDate: selectedBirthDate, deathDate: selectedDeathDate}));
//second try
addMemoria.initiate({firstName, lastName, birthDate: selectedBirthDate, deathDate: selectedDeathDate});

Ожидаемым результатом будет успешный запрос POST и новая запись Memoria в базе данных.

Ошибка, которую я получаю:

hydration-error-info.js?32aa:27 An unhandled error occurred processing a request for the endpoint "addMemoria".
In the case of an unhandled error, no tags will be "provided" or "invalidated". Error: Invariant: Method expects to have requestAsyncStorage, none available
    at headers (webpack-internal:///(:3000/e-memoria/app-client)/./node_modules/next/dist/client/components/headers.js:17:15)
    at getServerSession (webpack-internal:///(:3000/e-memoria/app-client)/./node_modules/next-auth/next/index.js:94:35)
    at prepareHeaders (webpack-internal:///(:3000/e-memoria/app-client)/./src/store/strapiApi.ts:23:90)
    at eval (webpack-internal:///(:3000/e-memoria/app-client)/./node_modules/@reduxjs/toolkit/dist/query/rtk-query.esm.js:239:42)
    at step (webpack-internal:///(:3000/e-memoria/app-client)/./node_modules/@reduxjs/toolkit/dist/query/rtk-query.esm.js:44:23)
    at Object.eval [as next] (webpack-internal:///(:3000/e-memoria/app-client)/./node_modules/@reduxjs/toolkit/dist/query/rtk-query.esm.js:25:53)

Следующий почтовый запрос действителен с использованием моего http-клиента:

POST http://localhost:1337/api/memorias
Content-Type: application/json
authorization: Bearer ****************************

{
  "data": {
    "firstName": "FirstNAmeTest",
    "lastName": "LAstNameTest",
    "birthDate": "2021-09-01",
    "deathDate": "2021-09-02"
  }
}

Конфигурация магазина РТК:

export const store = configureStore({
  reducer: {
    strapiApi: strapiApi.reducer,
  },
  middleware(getDefaultMiddleware) {
    return getDefaultMiddleware().concat(strapiApi.middleware);
  },
});

export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;

Моя конечная точка API (авторизованный запрос GET работает):

const baseQuery = fetchBaseQuery({
  baseUrl: process.env.STRAPI_API_URL + '/api/', //"http://localhost:3000/api/",
  prepareHeaders: async (headers, { getState }) => {
    const session : any = await getServerSession(authOptions);
    // If we have a token set in state, let's assume that we should be passing it.
    if (session) {
      headers.set('authorization', `Bearer ${session?.jwt}`)
    }
    headers.set('cache', 'no-store');
    headers.set('Cache-control', 'no-store, max-age=0');

    return headers
  },
})

export const strapiApi = createApi({
  reducerPath: "strapiApi",
  baseQuery: baseQuery,
  tagTypes: ["Memoria", "bla"],
  endpoints: (builder) => ({
    getAllMemorias: builder.query<{ results: Array<{ name: string }> }, void>({
      query: () => `memorias`,
      providesTags: ['bla'],

    }),
    addMemoria: builder.mutation<Memoria, Partial<Memoria>>({
      query: (body: Partial<Memoria>) => ({
        url: `memorias`,
        method: 'POST',
        body: createStrapiPOSTBody(body),
      }),
      invalidatesTags: [{ type: 'Memoria', id: 'LIST' }],
    }),
});

export const { getAllMemorias, addMemoria } = strapiApi.endpoints;
10 вопросов на собеседовании по React js
10 вопросов на собеседовании по React js
Вопрос: Что такое React JS? Каковы преимущества использования React?
0
0
629
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Насколько мне известно, вы можете вызывать getServerSession только в компонентах React Server. У вас нет доступа к заголовкам внутри клиентских компонентов, которые обрабатываются на сервере. Похоже, вы прямо сейчас вызываете его из клиентского компонента.

Как правило, вы также не должны использовать что-то вроде export const для магазина Redux в Next SSR, так как таким образом этот магазин будет использоваться несколькими пользователями. Tbh., нет хорошей истории о том, как все это сделать - это все еще очень экспериментально.

Уважаемый @phry, большое спасибо, что нашли время ответить на мой вопрос. Из вашего ответа я понял, что избыточность на стороне сервера не должна использоваться для каких-либо личных данных => никакие авторизованные вызовы API не должны выполняться с помощью RTK Q на сервере. Как посоветуете дальше поступить. Должен ли я делать редукцию только на стороне клиента и добавлять «использовать клиент» во все файлы моего магазина? Это означало бы, что вся платформа находится на стороне клиента. И я бы использовал только серверную часть, например, для блога, где люди должны выполнять только операции чтения. Лучший, Серджиу

Sergiu 31.03.2023 14:45

Даже файлы с «использованием запроса» будут выполняться на сервере и иметь эту проблему совместного использования глобальных переменных между запросами в дополнительном SSR, запускаемом после RSC. Для «традиционного» Next SSR это решает redux-next-wrapper. Для каталога app Next пока просто ничего нет. Имейте в виду, что здесь вы работаете с полностью экспериментальной технологией. Обязательно проведите много экспериментов и не запускайте ничего из этого в производственной среде, пока следующая команда не даст указаний о том, что это безопасно.

phry 31.03.2023 15:55

Или другими словами: экспериментировать приятно. Но если вы хотите создать какое-либо реальное приложение, не используйте каталог app. Он помечен как экспериментальный по какой-то причине.

phry 31.03.2023 15:56

Другие вопросы по теме