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 шт):
Я пытался воспроизвести у себя локально вашу ситуацию и у меня кое-что вышло. Во первых, 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,
},
};
}