禁用水合/仅部分水合Next.js应用

时间:2019-03-28 08:39:38

标签: reactjs next.js hydration

是否可以在Next.js中强制使用仅SSR 模式并且仅对页面进行部分补水?我的意思是说,我有这个应用程序:

components / dynamic.jsx

export default () => (
  <button onClick={() => console.log("I have been clicked")}>Click me</button>
)

pages / index.jsx

import DynamicComponent from "../components/dynamic.jsx";

export default () => (
  <div>
    <h1>Hello World</h1>
    <p>Lorem ipsum</p>
    <Hydrate>
      <DynamicComponent />
    </Hydrate>
  </div>
);

现在假设我们正在使用pages/index.jsx渲染Next.js,因此它将在服务器上渲染并在客户端上完全水合。出于性能方面的考虑(缩小捆绑包大小,减少执行时间),并使该应用更好地与广告()配合使用,我只想在客户端上填充DynamicComponent,充其量仅加载{{1} }给客户。

尽一切可能

  • 有反应吗?
  • Next.js?

谢谢

1 个答案:

答案 0 :(得分:2)

您可以通过修改来做到这一点:

<>
  <StaticContent>
    <h1>Hello World</h1>
    <p>Lorem ipsum</p>
  </StaticContent>
  <DynamicComponent />
</>

还有StaticContent组件:

import { createElement, useRef, useState, useEffect } from 'react'

function useStaticContent() {
  const ref = useRef(null)
  const [render, setRender] = useState(typeof window === 'undefined')

  useEffect(() => {
    // check if the innerHTML is empty as client side navigation
    // need to render the component without server-side backup
    const isEmpty = ref.current.innerHTML === ''
    if (isEmpty) {
      setRender(true)
    }
  }, [])

  return [render, ref]
}

export default function StaticContent({ children, element = 'div', ...props }) {
  const [render, ref] = useStaticContent()

  // if we're in the server or a spa navigation, just render it
  if (render) {
    return createElement(element, {
      ...props,
      children,
    })
  }

  // avoid re-render on the client
  return createElement(element, {
    ...props,
    ref,
    suppressHydrationWarning: true,
    dangerouslySetInnerHTML: { __html: '' },
  })
}
``