如何在不重新加载整个页面的情况下重新加载 Next.js 页面的初始属性。

4

我有一个 Next.js 页面,在 getInitialProps 函数中获取数据,我想在不重新加载页面的情况下从浏览器重新加载这些数据,因为重新加载会影响性能并且会丢失用户的滚动位置。是否有一种方法可以重新加载初始属性而不重新加载整个页面?

2个回答

17

可以通过调用router.replace来实现:

import { useRouter } from 'next/router';

function YourPage({ someProps }) {
  const router = useRouter();

  // Call this function when you want to refresh the data
  const refreshData = () => router.replace(router.asPath);

  // Your JSX
}

router.replace 是一种更新 URL 而不会在历史记录中新增条目的方法。router.asPath 表示当前的 URL。因此这就像是对同一页进行客户端重定向,而客户端重定向将重新获取 props。

上述答案不可行,因为函数无法从服务器序列化并发送到客户端。


这将清除所有状态和表单数据:/ - Aravin

2
您可以使用一个高阶组件来将上一次的初始属性存储为状态,并通过调用getInitialProps并将状态设置为其返回值来重新加载它们。以下是一个可以实现此功能的HOC:
import { NextPage, NextPageContext } from 'next';
import React, { useState, PropsWithChildren, ComponentType } from 'react';

/**
 * Removes never-used context values to reduce bloat. Context values may come from server but then
 * be used client-side because they are saved in initial props.
 */
function minifyContext(context) {
  return { ...context, req: undefined, res: undefined };
}

const withSoftReload = Page => {
  async function getInitialProps(ctx) {
    return { context: minifyContext(ctx), ...(await Page.getInitialProps(ctx)) };
  }
  const omitContextFromProps = ({
    context,
    ...props
  }) => props;
  const NewPage = props => {
    // set inner page initial props to wrapper initial props minus context
    const [initialProps, setInitialProps] = useState(omitContextFromProps(props));
    async function softReload() {
      setInitialProps({ children: null, ...(await Page.getInitialProps(props.context)) });
    }
    return (
      <Page
        {...{ ...initialProps, softReload }}
      />
    );
  };
  NewPage.getInitialProps = getInitialProps;
  NewPage.displayName = `withSoftReload(${Page.displayName})`;
  return NewPage;
};

export default withSoftReload;

在您的页面中,您可以像这样使用它:
const MyPage = ({ data, softReload }) => (
  <div>
    {data}
    <button onClick={softReload}>Refresh</button>
  </div>
);

MyPage.getInitialProps = async (ctx) => {
  // fetch data
};

export default withSoftReload(MyPage);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接