Comment fonctionne la directive "Utiliser le client" dans Next.js 13
P粉044526217
2023-08-26 21:55:31
<p>J'essaie d'en savoir plus sur le rendu côté serveur à l'aide de Next.js 13.4 et du nouveau répertoire <code>app/</code> D'après ce que j'ai compris, chaque composant est un composant <em>server</em> par défaut (c'est-à-dire rendu côté serveur). </p>
<p>Cependant, nous pouvons utiliser la directive <code>'use client'</code> pour forcer le composant à devenir un composant <em>client</em> </p>
<p> Ci-dessous, j'ai configuré un simple composant "Hello World", d'abord en tant que composant serveur puis en tant que composant client. Dans chaque cas, je compare le code source de la page.</p>
<h3><code>src/app/page.js</code>(服务器组件)</h3>
<pre class="brush:php;toolbar:false;">exporter la fonction par défaut Home() {
retour (
<principal>
<h1>Bonjour tout le monde</h1>
</principal>
)
}</pré>
<p>Chrome> 查看页面源代码</p>
<pre class="brush:php;toolbar:false;"><!DOCTYPE html>
<html lang="fr">
<tête>
<meta charSet="utf-8" />
<title>Créer l'application suivante</title>
<meta name="description" content="Généré par la création de l'application suivante" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script src="/_next/static/chunks/polyfills.js" noModule=""></script>
≪/tête>
<corps>
<principal>
<h1>Bonjour tout le monde</h1>
</principal>
<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__",{}]},"$undéfini","$undéfini",true],"initialHead":["$L3",null],"globalErrorComponent" :"$4","notFound":["$","html",null,{"lang":"fr","children":["$","body",null,{"children":[ "$L5","$undefined",[["$","title",null,{"children":"404 : Cette page est introuvable."}],["$","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": "Cette page est introuvable."}]}]]}]}]]]}]}],"asNotFound":false,"children":[["$","html",null,{"lang":"fr","children":["$","body",null,{" enfants":["$","$L6",null,{"parallelRouterKey":"enfants","segmentPath":["enfants"],"error":"$undéfini","errorStyles":"$undéfini ","loading":"$non défini","loadingStyles":"$undéfini","hasLoading":false,"template":["$","$L7",null,{}],"templateStyles": "$undéfini", "notFound": "$undéfini", "notFoundStyles": "$undéfini", "childProp": {"current":[["$","main",null,{"enfants":[ "$","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":"Créer l'application suivante"}],["$","meta",null,{"name":"description","content":"Généré par la création de l'application suivante"}],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>
</corps>
</html></pre>
<h3><code>src/app/page.js</code>(客户端组件)</h3>
<pre class="brush:php;toolbar:false;">'utiliser le client';
exporter la fonction par défaut Home() {
retour (
<principal>
<h1>Bonjour tout le monde</h1>
</principal>
)
}</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__",{}]},"$undéfini","$undéfini",true],"initialHead":["$L3",null],"globalErrorComponent" :"$4","notFound":["$","html",null,{"lang":"fr","children":["$","body",null,{"children":[ "$L5","$undefined",[["$","title",null,{"children":"404 : Cette page est introuvable."}],["$","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": "Cette page est introuvable."}]}]]}]}]]]}]}],"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":"Créer l'application suivante"}],["$","meta",null,{"name":"description","content":"Généré par la création de l'application suivante"}],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>
</corps>
</html></pre>
<heure />
<p>于 React et DOM 节点的东西 - 基本上是一个空的div 等待注入一些 HTML。我在这里缺少什么?</p>
D'ici
Les composants serveur et client sont rendus différemment lors du rendu statique :
Maintenant, avec Composants serveur et client, React peut effectuer le rendu à la fois sur le client et sur le serveur, ce qui signifie que vous pouvez choisir l'environnement de rendu au niveau du composant.
Par défaut,
app
Router utilise des Composants du serveur, vous permettant de restituer facilement les composants sur le serveur et de réduire la quantité de JavaScript envoyée au client.