是否可以在Next.js中强制实现仅SSR模式,并且仅对页面进行部分 hydration 处理?假设我有这个应用程式:

组件/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,因此它将在服务器上渲染并在客户端上完全 hydration 。出于性能方面的考虑(缩小捆绑包大小,减少执行时间),并使应用更好地与广告一起播放(😒),我只想在客户端上混合DynamicComponent,充其量只将DynamicComponent的JavaScript加载到客户端。

尽力做到
  • react ?
  • Next.js?

  • 谢谢

    最佳答案

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

    <>
      <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: '' },
      })
    }
    ``
    

    关于reactjs - 禁用 hydration/仅部分 hydration Next.js应用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55393226/

    10-14 14:54