Next js - 在某些页面上禁用服务器端渲染

Next js - disable server side rendering on some pages

是否可以使用 Next js 在某些页面上禁用 ssr?例如,我有一个包含产品描述的页面,我在该页面上使用 ssr 进行 SEO,但我也有一个包含我可以过滤的项目或产品列表的页面,对于该页面,我不想使用 ssr 因为这个页面每次都动态生成,如何在该页面上禁用 ssr?

延迟加载组件并禁用 SSR:https://nextjs.org/docs/advanced-features/dynamic-import#with-no-ssr

import dynamic from 'next/dynamic'

const DynamicComponentWithNoSSR = dynamic(() => import('../components/List'), {
  ssr: false
})

export default () => <DynamicComponentWithNoSSR />

这是一个迟到的答案,但万一有人遇到这个问题:

const isServer = () => typeof window === `undefined`;

const Page = () => isServer() ? null : (

  <> 
      <YourClientSideComponent />
  </>
);

这是 "page" 级别。 isServer() 阻止在服务器端呈现任何内容。如果你愿意,你也可以在组件级别阻止 ssr:

const isServer = () => typeof window === `undefined`;

const Page = () =>(

  <> 
      { !isServer() && <YourClientSideComponent /> }
  </>
);

dynamic() 函数也可以在没有动态导入的情况下使用:

import dynamic from 'next/dynamic'
import React from 'react'

const NoSsr = props => (
  <React.Fragment>{props.children}</React.Fragment>
)

export default dynamic(() => Promise.resolve(NoSsr), {
  ssr: false
})

包含在该组件中的任何内容在 SSR 源中都将不可见。

Contact me at <NoSsr>email@example.com</NoSsr>

这是我刚刚根据 React 文档中提到的内容提出的解决方案:https://reactjs.org/docs/react-dom.html#hydrate

class ClientOnly extends React.Component {
  state = {
    isClient: false,
  };

  componentDidMount() {
    this.setState({
      isClient: true,
    });
  }

  render() {
    const { isClient } = this.state;
    const { children } = this.props;

    return isClient ? children : false;
  }
}

然后您可以用它包装任何组件/块,它不会在服务器上呈现。例如

<ClientOnly>You're logged in as {name}</ClientOnly>

这也可以防止以下 React.hydrate 警告“警告:预期服务器 HTML 包含匹配。”

我们也可以使用react-no-ssr React组件。

假设评论是我们的客户端组件。现在我们只需要在客户端渲染它。以下是我们的做法。

import React from 'react';
import NoSSR from 'react-no-ssr';
import Comments from './comments.jsx';

const MyPage = () => (
  <div>
    <h2>My Blog Post</h2>
    <hr />
    <NoSSR>
      <Comments />
    </NoSSR>
  </div>
);

另一个我认为最简单的解决方案是只使用 process.browser,只有在客户端 运行 时才会如此。

<div>
  {
    process.browser && <Hidden />
  }
</div>

把这个放在你的_app.tsx

import type { AppProps } from "next/app";
import dynamic from "next/dynamic";
import React from "react";

const App = ({ Component, pageProps }: AppProps) => {
  return <Component {...pageProps} />;
};

export default dynamic(() => Promise.resolve(App), {
  ssr: false,
});