优化从getServerSideProps对外部Api的调用

时间:2020-11-11 11:20:13

标签: next.js server-side-rendering

假设我的next.js react应用程序具有以下页面:

// 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 /时,URL中的字符串siteX用于调用其他系统上的外部(!)api。 https:// external-api / siteX。到目前为止,此方法运行良好,但我看到以下性能问题:

在浏览器中,当我单击<Link>时,发生了两个请求:一个请求到我自己的服务器以使用新路径更新getServerSideProps,第二个请求从我的服务器更新为https:/ / external-api / ...以获取新数据。

您看到一种优化方法吗?我想要的是:

  • 单击<Link>时,仅直接向https:// external-api / ...发出一个请求,并且data被直接更新(例如,作为MyPage的状态)。
  • li>
  • 现在,访问http:// localhost:3000 / siteX /时,服务器应获取数据并预渲染站点

我当然可以将data视为<MyPage>的状态,只需单击<Link>即可调用一个函数以请求更新它。但是我也想要正确的路由,历史记录等等。

您能帮我吗?谢谢!

1 个答案:

答案 0 :(得分:0)

再进行一些研究后,我遇到了一个解决方案。 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 } };
}