「使用客戶端」指令在 Next.js 13 中如何運作
P粉044526217
P粉044526217 2023-08-26 21:55:31
0
1
594
<p>我正在嘗試使用 Next.js 13.4 和新的 <code>app/</code> 目錄來了解伺服器端渲染。據我了解,預設情況下每個元件都是一個<em>伺服器</em>元件(即在伺服器端呈現)。 </p> <p>但是,我們可以使用 <code>'use client'</code> 指令來強制將元件變成<em>客戶端</em>元件。 </p> <p>下面,我設定了一個簡單的「Hello World」元件,首先作為伺服器元件,然後作為客戶端元件。在每種情況下,我都會比較頁面原始碼。</p>

src/app/page.js(伺服器元件)

; <pre class="brush:php;toolbar:false;">匯出預設函數 Home() { 返回 ( <主要>

你好世界

</主要> ) }</pre> <p>Chrome>查看來源頁面代碼</p>
;
<html lang="zh-cn">

<頭>
  
  建立下一個應用程式
  
  <元名稱=“視口”內容=“寬度=設備寬度,初始比例= 1”/> />
  ;
</頭>

<正文>
  <主要>
    

你好世界

</主要> ; ; ; <腳本>self.__next_f.push([1, "0:"$L1"n"])</腳本> <script>self.__next_f.push([1, "2:I{"id":"(app-client)/./node_modules/next/dist/client/components/app-router.js","區塊":["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>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"],"名稱":"","async":false}n"]) <script>self.__next_f.push([1, "1:[[],["$","$L2",null,{"assetPrefix":"","initialCanonicalUrl":"/","initialTree ":["",{"children":["__PAGE__",{}]},"$未定義","$未定義",true],"initialHead":["$L3",null]," globalErrorComponent" :"$4","notFound":["$","html",null,{"lang":"en","children":["$","body",null,{"children" :[ "$L5","$undefined",[["$","title",null,{"children":"404: 找不到此頁。"}],["$","div" , null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color 表情符號\",\"Segoe UI 表情符號\"" ,"height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center "}, "children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color: #000;背景:#fff;邊距:0}.next-error-h1{border-right:1px 實心rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){ body{顏色: #fff;背景:#000}.next-error-h1{border-right:1px 實心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":"找不到此頁。"}]}]]}]}]]]}]}],"asNotFound":false,"children":[["$","html",null,{"lang":"en","children":["$","body",null,{"孩子”:[“$”,“$L6”,null,{“parallelRouterKey”:“孩子”,“segmentPath”:[“孩子”],“錯誤”:“$未定義”,“errorStyles”:“$未定義","loading":"$undefined","loadingStyles":"$undefined","hasLoading":false,"template":["$","$L7",null,{}],"templateStyles ": “$未定義”,“notFound”:“$未定義”,“notFoundStyles”:“$未定義”,“childProp”:{“目前”:[[“$”,“main”,null,{ 「children」:[ "$","h1",null,{"children":"Hello World"}]}],null],"segment":"__PAGE__"},"styles":[]}]} ]}],null ]}]]n"]) <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":"視口","content":"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":"建立下一個應用程式"}],["$","meta",null,{"name":"description","content":"由建立下一個應用程式產生"} ],null, null,null,null,n"]); ; </正文> </html></pre>

src/app/page.js(客戶端元件)

'使用客戶端';

導出預設函數 Home() {
  返回 (
    <主要>
      

你好世界

</主要> ) }</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>self.__next_f.push([1, "1:[[],["$","$L2",null,{"assetPrefix":"","initialCanonicalUrl":"/","initialTree ":["",{"children":["__PAGE__",{}]},"$未定義","$未定義",true],"initialHead":["$L3",null]," globalErrorComponent" :"$4","notFound":["$","html",null,{"lang":"en","children":["$","body",null,{"children" :[ "$L5","$undefined",[["$","title",null,{"children":"404: 找不到此頁。"}],["$","div" , null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color 表情符號\",\"Segoe UI 表情符號\"" ,"height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center "}, "children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color: #000;背景:#fff;邊距:0}.next-error-h1{border-right:1px 實心rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){ body{顏色: #fff;背景:#000}.next-error-h1{border-right:1px 實心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":"找不到此頁。"}]}]]}]}]]]}]}],"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>self.__next_f.push([1, "5:[[["$","meta",null,{"charSet":"utf-8"}],null,null,null,null, null,null,null,null,null,null,["$","meta",null,{"name":"視口","content":"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":"建立下一個應用程式"}],["$","meta",null,{"name":"description","content":"由建立下一個應用程式產生"} ],null, null,null,null,n"]); ; </正文> </html></pre> <小時/>> <p>我很困惑,因為客戶端元件似乎已經預先渲染了 HTML,但「Hello World」顯然存在於原始程式碼中。我希望看到一個 React 根 DOM 節點的東西 - 基本上是一個空的div等待注入一些HTML。我這裡缺什麼?</p>
P粉044526217
P粉044526217

全部回覆(1)
P粉268654873

從這裡

伺服器和客戶端元件在靜態渲染期間的渲染方式不同:

  • 客戶端元件的 HTML 和 JSON 已預先渲染並快取在伺服器上。然後將快取的結果傳送到客戶端進行水合作用。
  • 伺服器元件由 React 在伺服器上呈現,其負載用於產生 HTML。相同的渲染負載也用於混合客戶端上的元件,從而導致客戶端不需要 JavaScript。

現在,透過伺服器和客戶端元件,React 可以在客戶端伺服器上進行渲染,這意味著您可以在元件層級選擇渲染環境。

預設情況下,app 路由器使用伺服器元件,讓您可以輕鬆地在伺服器上渲染元件並減少發送到客戶端的 JavaScript 量。

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!