#next.js #server-side-rendering
#next.js #рендеринг на стороне сервера
Вопрос:
Предположим, у меня есть следующая страница в моем next.js реагирующее приложение:
// Filename: [mypath].jsx
export default function MyPage(props) {
return (
<>
<Link href="/siteX">
<a>Go to siteX</a>
</Link>
<Link href="/siteY">
<a>Go to siteY</a>
</Link>
<div>{props.data.text}</div>
</>
);
}
export async function getServerSideProps(context) {
const mypath = context.params.mypath;
const res = await fetch(`https://external-api/${mypath}`)
const data = await res.json();
return { props: { data } };
}
Когда я обращаюсь http://localhost:3000/siteX / на стороне сервера строка siteX
из URL-адреса используется для вызова внешнего (!) api в другой системе, например https://external-api/siteX . Пока это работает нормально, но я вижу следующую проблему с производительностью:
В браузере, когда я нажимаю на a <Link>
, происходит два запроса: один на мой собственный сервер для обновления getServerSideProps
с новым путем, а второй с моего сервера на https://external-api /… для получения новых данных.
Вы видите способ оптимизировать это? Чего я хочу, так это:
- при нажатии на
<Link>
есть только один запрос непосредственно к https://external-api /… происходит иdata
обновляется напрямую (например, как состояние MyPage). - Как и сейчас, при доступе http://localhost:3000/siteX / сервер должен получить данные и выполнить предварительный просмотр сайта
Я мог бы, конечно, рассматривать data
как состояние <MyPage>
и просто вызывать функцию, чтобы обновить ее запросом при <Link>
нажатии. Но я также хочу правильную маршрутизацию, историю и так далее.
Можете ли вы мне помочь с этим? Спасибо!
Ответ №1:
После еще нескольких повторных поисков я наткнулся на решение. next.js у <Link>
компонента есть свойство shallow
, которое я могу установить , чтобы предотвратить выполнение getServersideProps
. Таким образом, я могу запрашивать новые данные вручную при нажатии на ссылку. Тем не менее, начальный запрос данных выполняется getServersideProps
на сервере, и мой внутренний SSR работает по-прежнему.
// Filename: [mypath].jsx
export default function MyPage(props) {
const [data, setData] = useState(props.data);
function updateData(path) {
const res = await fetch(`https://external-api/${path}`)
const data = await res.json();
setData(data);
}
return (
<>
<!-- Manually query and set data -->
<div onClick={() => updateData("siteX")}>
<!-- Trigger routing, but don't execute getServerSideProps (because of shallow={true}) -->
<Link href="/siteX" shallow={true}>
<a>Go to siteX</a>
</Link>
</div>
<div onClick={() => updateData("siteY")}>
<Link href="/siteY" shallow={true}>
<a>Go to siteY</a>
</Link>
</div>
<div>{props.data.text}</div>
</>
);
}
// If page is requested directly via url (and not because a <Link> element has been clicked) do SSR as before
export async function getServerSideProps(context) {
const mypath = context.params.mypath;
const res = await fetch(`https://external-api/${mypath}`)
const data = await res.json();
return { props: { data } };
}