Next js проблема с fetch запросом

Прошу помощи: сделала пагинацию в Next js и теперь при переходе на страницу с товарами - пустая страница с кнопками Prev и Next. Товары подгружаются только когда нажимаешь кнопки, а надо чтобы первые 8 сразу были. Подозреваю, что ошибка из-за этой строчки items: data.products ?? null, и при переходе, пока данные не загрузились, я получаю null. Но если ?? null, убрать, то выскакивает ошибка "Server Error Error: Error serializing .items returned from getServerSideProps in "/items". Reason: undefined cannot be serialized as JSON. Please use null or omit this value." До пагинации все работало как надо(( Что не так?

index.js

import Layout from "../../components/Layout"
import styles from "../../styles/Items.module.scss"
import {useState, useEffect} from 'react'
import {useRouter} from 'next/router'
import ItemModel from "../../components/ItemModel"

const Items = ({items}) => {
  const [skip, setSkip] = useState(0)
  const router = useRouter()
  const {query} = router

  useEffect(() => {
    if(query.skip) {
      let num = Number(query.skip) >= 8 ? query.skip : 0
      setSkip(Number(num))
    }
    console.log(query)
  }, [query])

  const handlePaginate = (skipNum) => {
    let s = skipNum >= 8 ? skipNum : 0
    router.replace(`?skip=${s}&limit=8`)
  }
    return (
        <>
            <Layout>
              <ul className={styles.list}>
                {items !== null && items.map(el => 
                    <li key={el.id}>
                      <ItemModel item={el}/>
                    </li>
                  )}
              </ul>
              <div className={styles.buttons}>
                <button  onClick={() => handlePaginate(skip - 8)} >Prev</button>
                <button  onClick={() => handlePaginate(skip  + 8)} >Next</button>
              </div>
            </Layout>
        </>
    )
}

export async function getServerSideProps(context){
  const {query} = context
 
  const response = await fetch(`https://dummyjson.com/products/?skip=${query.skip}&limit=${query.limit}`)
  const data  = await response.json()
 
  if(!data) {
    return {
      notFound: true,
    }
  } 
  return {
    props: {
      items: data.products,
      revalidate: 1
    },
  }
}

export default Items

Ответы (1 шт):

Автор решения: Sergey Bogdanets

Я пытался воспроизвести у себя локально вашу ситуацию и у меня кое-что вышло. Во первых, getServerSideProps вынес за пределы экспорта компонента. Во вторых, поставил в запросе захардкоженные параметры, ибо я не понял, что вы там из query достаёте(я выводил в консоль и у меня ничего не было, и на это ругалось апи.) Ну не суть, думаю, что с запросом разберётесь. Я убрал парочку компонентов, так как их у меня нет и в итоге у меня получился такой компонент, который выводит 10 лишек, как и указано в параметрах запроса. Надеюсь, это вам поможет.

import { useState, useEffect } from 'react';
import { useRouter } from 'next/router';

const Items = ({ items }) => {
    const [skip, setSkip] = useState(0);
    const router = useRouter();
    const { query } = router;

    useEffect(() => {
        if (query.skip) {
            let num = Number(query.skip) >= 8 ? query.skip : 0;
            setSkip(Number(num));
        }
    }, [query]);

    const handlePaginate = (skipNum) => {
        let s = skipNum >= 8 ? skipNum : 0;
        router.replace(`?skip=${s}&limit=8`);
    };
    return (
        <>
            <ul>
                {items && items.map((el) => <li key={el.id}>{el.brand}</li>)}
            </ul>
            <div>
                <button onClick={() => handlePaginate(skip - 8)}>Prev</button>
                <button onClick={() => handlePaginate(skip + 8)}>Next</button>
            </div>
        </>
    );
};

export default Items;

export async function getServerSideProps() {
    const response = await fetch(
        `https://dummyjson.com/products/?skip=1&limit=10`
    );
    const data = await response.json();

    if (!data) {
        return {
            notFound: true,
        };
    }
    return {
        props: {
            items: data.products,
            revalidate: 1,
        },
    };
}

→ Ссылка