How the "Use Client" directive works in Next.js 13
P粉044526217
P粉044526217 2023-08-26 21:55:31
0
1
595
<p>I'm trying to learn about server-side rendering using Next.js 13.4 and the new <code>app/</code> directory. From what I understand, every component is a <em>server</em> component by default (i.e. rendered on the server side). </p> <p>However, we can use the <code>'use client'</code> directive to force the component to become an <em>client</em> component. </p> <p>Below, I've set up a simple "Hello World" component, first as a server component and then as a client component. In each case, I compare the page source code.</p> <h3><code>src/app/page.js</code>(服务器组件)</h3> <pre class="brush:php;toolbar:false;">export default function Home() { return ( <main> <h1>Hello World</h1> </main> ) }</pre> <p>Chrome > 查看页面源代码</p> <pre class="brush:php;toolbar:false;"><!DOCTYPE html> <html lang="en"> <head> <meta charSet="utf-8" /> <title>Create Next App</title> <meta name="description" content="Generated by create next app" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <script src="/_next/static/chunks/polyfills.js" noModule=""></script> </head> <body> <main> <h1>Hello World</h1> </main> <script src="/_next/static/chunks/webpack.js" async=""></script> <script src="/_next/static/chunks/main-app.js" async=""></script> <script>(self.__next_f = self.__next_f || []).push([0])</script> <script>self.__next_f.push([1, "0:"$L1"n"])</script> <script>self.__next_f.push([1, "2:I{"id":"(app-client)/./node_modules/next/dist/client/components/app-router.js","chunks":["webpack:static/chunks/webpack.js"],"name":"","async":false}n4:I{"id":"(app-client)/./node_modules/next/dist/client/components/error-boundary.js","chunks":["webpack:static/chunks/webpack.js"],"name":"","async":false}n6:I{"id":"(app-client)/./node_modules/next/dist/client/components/layout-router.js","chunks":["app-client-internals:static/chunks/app-client-internals.js"],"name":"","async":false}n7:I{"id":"(app-client)/"])</script> <script>self.__next_f.push([1, "./node_modules/next/dist/client/components/render-from-template-context.js","chunks":["app-client-internals:static/chunks/app-client-internals.js"],"name":"","async":false}n"])</script> <script>self.__next_f.push([1, "1:[[],["$","$L2",null,{"assetPrefix":"","initialCanonicalUrl":"/","initialTree":["",{"children":["__PAGE__",{}]},"$undefined","$undefined",true],"initialHead":["$L3",null],"globalErrorComponent":"$4","notFound":["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$L5","$undefined",[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]]]}]}],"asNotFound":false,"children":[["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","loading":"$undefined","loadingStyles":"$undefined","hasLoading":false,"template":["$","$L7",null,{}],"templateStyles":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined","childProp":{"current":[["$","main",null,{"children":["$","h1",null,{"children":"Hello World"}]}],null],"segment":"__PAGE__"},"styles":[]}]}]}],null]}]]n"])</script> <script>self.__next_f.push([1, "5:[[["$","meta",null,{"charSet":"utf-8"}],null,null,null,null,null,null,null,null,null,null,["$","meta",null,{"name":"viewport","content":"width=device-width, initial-scale=1"}],null,null,null,null,null,null,null,null,null,null,[]],[null,null,null,null],null,null,[null,null,null,null,null],null,null,null,null,null]n3:[[["$","meta",null,{"charSet":"utf-8"}],["$","title",null,{"children":"Create Next App"}],["$","meta",null,{"name":"description","content":"Generated by create next app"}],null,null,null,null,n"])</script> <script>self.__next_f.push([1, "ull,null,null,null,["$","meta",null,{"name":"viewport","content":"width=device-width, initial-scale=1"}],null,null,null,null,null,null,null,null,null,null,[]],[null,null,null,null],null,null,[null,null,null,null,null],null,null,null,null,null]n"])</script> </body> </html></pre> <h3><code>src/app/page.js</code>(客户端组件)</h3> <pre class="brush:php;toolbar:false;">'use client'; export default function Home() { return ( <main> <h1>Hello World</h1> </main> ) }</pre> <p>Chrome > 查看页面源代码</p> <pre class="brush:php;toolbar:false;"><!DOCTYPE html> <html lang="en"> <head> <meta charSet="utf-8" /> <title>Create Next App</title> <meta name="description" content="Generated by create next app" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <script src="/_next/static/chunks/polyfills.js" noModule=""></script> </head> <body> <main> <h1>Hello World</h1> </main> <script src="/_next/static/chunks/webpack.js" async=""></script> <script src="/_next/static/chunks/main-app.js" async=""></script> <script>(self.__next_f = self.__next_f || []).push([0])</script> <script>self.__next_f.push([1, "0:"$L1"n"])</script> <script>self.__next_f.push([1, "2:I{"id":"(app-client)/./node_modules/next/dist/client/components/app-router.js","chunks":["webpack:static/chunks/webpack.js"],"name":"","async":false}n4:I{"id":"(app-client)/./node_modules/next/dist/client/components/error-boundary.js","chunks":["webpack:static/chunks/webpack.js"],"name":"","async":false}n6:I{"id":"(app-client)/./node_modules/next/dist/client/components/layout-router.js","chunks":["app-client-internals:static/chunks/app-client-internals.js"],"name":"","async":false}n7:I{"id":"(app-client)/"])</script> <script>self.__next_f.push([1, "./node_modules/next/dist/client/components/render-from-template-context.js","chunks":["app-client-internals:static/chunks/app-client-internals.js"],"name":"","async":false}n8:I{"id":"(app-client)/./src/app/page.js","chunks":["app/page:static/chunks/app/page.js"],"name":"","async":false}n"])</script> <script>self.__next_f.push([1, "1:[[],["$","$L2",null,{"assetPrefix":"","initialCanonicalUrl":"/","initialTree":["",{"children":["__PAGE__",{}]},"$undefined","$undefined",true],"initialHead":["$L3",null],"globalErrorComponent":"$4","notFound":["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$L5","$undefined",[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]]]}]}],"asNotFound":false,"children":[["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","loading":"$undefined","loadingStyles":"$undefined","hasLoading":false,"template":["$","$L7",null,{}],"templateStyles":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined","childProp":{"current":[["$","$L8",null,{"params":{},"searchParams":{}}],null],"segment":"__PAGE__"},"styles":[]}]}]}],null]}]]n"])</script> <script>self.__next_f.push([1, "5:[[["$","meta",null,{"charSet":"utf-8"}],null,null,null,null,null,null,null,null,null,null,["$","meta",null,{"name":"viewport","content":"width=device-width, initial-scale=1"}],null,null,null,null,null,null,null,null,null,null,[]],[null,null,null,null],null,null,[null,null,null,null,null],null,null,null,null,null]n3:[[["$","meta",null,{"charSet":"utf-8"}],["$","title",null,{"children":"Create Next App"}],["$","meta",null,{"name":"description","content":"Generated by create next app"}],null,null,null,null,n"])</script> <script>self.__next_f.push([1, "ull,null,null,null,["$","meta",null,{"name":"viewport","content":"width=device-width, initial-scale=1"}],null,null,null,null,null,null,null,null,null,null,[]],[null,null,null,null],null,null,[null,null,null,null,null],null,null,null,null,null]n"])</script> </body> </html></pre> <hr /> <p>我很困惑,因为客户端组件似乎已预渲染了 HTML,但“Hello World”显然存在于源代码中。我期望看到类似于 React 根 DOM 节点的东西 - 基本上是一个空的 div 等待注入一些 HTML。我在这里缺少什么?</p>
P粉044526217
P粉044526217

reply all(1)
P粉268654873

from here

Server and client components are rendered differently during static rendering:

  • HTML and JSON for client components are pre-rendered and cached on the server. The cached results are then sent to the client for hydration.
  • Server components are rendered on the server by React, and their payload is used to generate HTML. The same rendering load is also used to mix components on the client side, resulting in no JavaScript being required on the client side.

Now, with Server and Client Components , React can render on both the client and the server, which means you can choose the rendering environment at the component level.

By default, app Router uses server components, allowing you to easily render components on the server and reduce the amount of JavaScript sent to the client.

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!