Next.js перепутал ответы API

Я пытаюсь разработать свое первое приложение с помощью Next.js, и тут происходит кое-что, что меня действительно беспокоит.

Мое приложение делает 2 запроса после первой загрузки, /api/me а также /api/feed

Мой компонент получает такие данные:

      useEffect(() => {
  async function loadData() {
    const res = await fetch('/api/me');
    try {
      const body = await res.json();
      if (body.error) {
        return router.push('/login');
      }
      setUser(body.user);
    } catch (e) {
      router.push('/login');
    }
  }
  loadData();
}, []);

useEffect(() => {
  async function loadFeed() {
    const res = await fetch('/api/feed');
    const body = await res.json();
    console.log('fetch', body.data);
    setFeed(body.data);
  }

  if (user) {
    loadFeed();
  }
}, [user]);

Моя проблема в том, что иногда при перезагрузке ответы смешиваются. возвращает массив и объект. При перезагрузке бывает раз как и получает объект из /me, иногда они оба получают массив из /feed, иногда работает правильно. Я не нашел никого, кто сообщал бы о подобной ошибке, поэтому предполагаю, что это ошибка где-то с моей стороны.

/pages/feed/api.js

      import handler from '../../helpers/routes/handler';
import auth from '../../middlewares/auth';
import * as feedController from '../../controllers/feed';

export default handler
  .use(auth)
  .get((req, res) => feedController.get(req, res));

handler.js

      import nextConnect from 'next-connect';
import { getSession } from '../../config/passport/encrypt';

const handler = nextConnect()
  .use(async (req, res, next) => {
    const session = await getSession(req);

    if (!session) {
      return next();
    }
    ...
    next();
  });

export default handler;

controllers/feed.js

      import * as expertMarketerService from '../services/expert_marketer';

// eslint-disable-next-line import/prefer-default-export
export const get = async (req, res) => {
  const data = await expertMarketerService.get(req.user);
  return res.status(200).send({ data });
};

pages/api/me.js

      import handler from '../../helpers/routes/handler';
import auth from '../../middlewares/auth';

export default handler
  .use(auth)
  .get((req, res) => res.status(200).send({ user: req.user }));

2 ответа

Решение

Я нашел для этого решение. Была такая же проблема. Я создал и экспортировал модуль вместо прямого экспорта. вот мой код

      import nc from 'next-connect';
import someCommonMiddleware from '..some-common-middlware-path';

module globalHandler {
    const config = {
        onError : (error, req, res) => {
            // handle errors
        }
    };
    export function handle() {
        return nc(config)
        .use(someCommonMiddleware);
    }
}

export default globalHandler;

Тогда вы можете использовать это так

      import { NextApiRequest, NextApiResponse } from 'next';
import globalHandler  from '..your-global-handler-path';

const handler = globalHandler.handle()
    .get(async (req: NextApiRequest, res: NextApiResponse) => {
        // handle url api response here
    });

export default handler;

Я нашел проблему. Я использовал один и тот же экземпляр next-connect для разных маршрутов, и это бесполезно.

https://github.com/hoangvvo/next-connect/issues/106

Решение импортирует следующее соединение для каждой страницы и использует промежуточное ПО для этой общей логики.

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