Оптимизация вызовов внешнего API из getServerSideProps

#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 } };
}