<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          推薦一個(gè) React Server Component 在大公司的落地案例

          共 6257字,需瀏覽 13分鐘

           ·

          2022-02-19 03:04

          Shopify 是國外的一個(gè)允許客戶自由搭建商城的 no code 產(chǎn)品,工程師 Cathryn Griffiths 分享了他在 Shopify 中實(shí)用 React Server Component 的最佳實(shí)踐。

          Hydrogen 是基于 React 的框架用來創(chuàng)建自定義店面的框架,他們試用 RSC(React Server Component)有兩個(gè)理由:

          1. 再見了,臃腫的 bundle 體積,你好,更棒的購物體驗(yàn)!
          2. 技術(shù)人的一種自私情結(jié):這玩意一定很有趣!

          這是一件很有挑戰(zhàn)性的事。RSC 是一種范式轉(zhuǎn)變,一開始他們遇到的問題是構(gòu)建的客戶端組件太多,服務(wù)器組件太少。經(jīng)過數(shù)月的反復(fù)嘗試和重構(gòu)才找到較好的方案。

          這篇文章將著重討論工程師在構(gòu)建 Hydrogen 時(shí)候發(fā)現(xiàn)的 RSC 最佳實(shí)踐,不光是對個(gè)人的,也是對團(tuán)隊(duì)的。希望能讓讀者們更加理解如何在 RSC 應(yīng)用中編寫組件,減少你的無效時(shí)間。

          優(yōu)先寫共享組件

          當(dāng)你需要在 RSC 應(yīng)用程序中從頭構(gòu)建組件時(shí),請從共享組件開始。共享組件可以同時(shí)在服務(wù)器和客戶端上下文中執(zhí)行,而不會出現(xiàn)任何問題。它們是客戶端和服務(wù)器組件之間的天然中間地帶,是個(gè)不錯(cuò)的起點(diǎn)。

          從中間地帶開始,可以幫助你更好的思考,引導(dǎo)你構(gòu)建正確類型的組件。你必須問自己:“這段代碼只能在客戶機(jī)上運(yùn)行嗎?”,類似地,“這段代碼應(yīng)該在客戶機(jī)上執(zhí)行嗎?”下一節(jié)列出了一些您應(yīng)該問的問題。

          不要總是默認(rèn)構(gòu)建客戶端組件。雖然方便,但最后應(yīng)用程序會太臃腫,很多組建更適合在服務(wù)端運(yùn)行。

          在少數(shù)情況下選擇客戶端組件

          RSC 應(yīng)用程序中的大多數(shù)組件應(yīng)該是服務(wù)器組件,因此在確定是否需要客戶端組件時(shí),需要仔細(xì)分析用例。

          通常只有客戶端特定的邏輯部分需要被提取到客戶端組件中:

          • 整合客戶端交互性
          • 用了 useStateuseReducer
          • 用了生命周期渲染邏輯(比如 useEffect
          • 用了不支持 RSC 的第三方庫
          • 用了服務(wù)端不支持的瀏覽器 APIs

          重要說明:不要只是盲目將整個(gè)共享組件轉(zhuǎn)換為客戶端組件。相反,有意地提取需要的特定功能。這有助于保持您的客戶端組件和 bundle 尺寸盡可能的小。文章末尾會有一些示例。

          盡可能以服務(wù)端組件為主

          如果組件不包含任何客戶端組件用例,那么它應(yīng)該被改為服務(wù)器組件(如果它符合以下條件之一):

          • 該組件包含不應(yīng)該在客戶端上暴露的代碼,如專用業(yè)務(wù)邏輯和密鑰。

          • 客戶端組件中不會使用該組件。(RSC 的限制,客戶端組件中不能直接導(dǎo)入服務(wù)端組件)

          • 代碼從不在客戶端上執(zhí)行(據(jù)你所知)。

          • 代碼需要訪問文件系統(tǒng)或數(shù)據(jù)庫(客戶端上不可用)。

          • 代碼需要從 StoreFront API 獲取數(shù)據(jù)(在 Hydrogen 中特定的情況)。

          如果組件需要在客戶端組件中使用,可以先深入研究用例和實(shí)現(xiàn)。很可能你可以將組件實(shí)例作為 children props 傳遞給客戶端組件,而不是讓客戶端組件直接導(dǎo)入并實(shí)用它。這樣就不需要把組件轉(zhuǎn)換為客戶端組件了。

          探索一些例子

          有很多東西需要記住,我們可以用 Hydrogen 啟動模板[1]來試幾個(gè)例子。

          訂閱注冊

          第一個(gè)示例是一個(gè)組件,它允許買家注冊訂閱我的在線商店的時(shí)事通訊。它出現(xiàn)在每個(gè)頁面的頁腳,看起來像這樣:

          我們從一個(gè)名為 NewsletterSignup.jsx的共享組件開始:

          export?default?function?NewsletterSignup()?{
          ??return?(
          ????<div>
          ??????<p>
          ????????Sign?up?for?our?newsletter?to?never?miss?out?on?latest?news?and?product
          ????????drops!
          ??????p>

          ??????<label?for="emailInput">Emaillabel>
          ??????<input?type="text"?id="emailInput"?name="email"?placeholder="Email"?/>
          ??????<button
          ????????onClick={()?=>
          ?{
          ??????????/*?TODO?*/
          ????????}}
          ??????>
          ????????Sign?me?up
          ??????button>
          ????div>
          ??);
          }

          在這個(gè)組件中,我們有兩個(gè)客戶端交互部分(輸入字段和提交按鈕),這說明這個(gè)當(dāng)前編寫的組件不能是共享組件。

          我們別將其完全轉(zhuǎn)換為客戶端組件,而是將客戶端功能提取到一個(gè)單獨(dú)的 NewsletterSignupForm.client.jsx組件里:

          export?default?function?NewsletterSignupForm()?{
          ??return?(
          ????<>
          ??????<label?for="emailInput">Emaillabel>

          ??????<input?type="text"?id="emailInput"?name="email"?placeholder="Email"?/>
          ??????<button
          ????????onClick={()?=>
          ?{
          ??????????/*?TODO?*/
          ????????}}
          ??????>
          ????????Sign?me?up
          ??????button>
          ????
          ??);
          }

          然后更新 NewsletterSignup 組件來使用這個(gè)客戶端組件:

          import?NewsletterSignupForm?from?'./NewsletterSignupForm.client';

          export?default?function?NewsletterSignup()?{
          ??return?(
          ????<div>
          ??????<p>
          ????????Sign?up?for?our?newsletter?to?never?miss?out?on?latest?news?and?product
          ????????drops!
          ??????p>

          ??????<NewsletterSignupForm?/>
          ????div>
          ??);
          }

          我們很容易到此為止,并將 NewsletterSignup 組件保持為一個(gè)共享組件。然而我知道這個(gè)組件只在我的在線商店的頁腳中使用,而我的頁腳組件是一個(gè)服務(wù)端組件。所以它不需要是一個(gè)共享組件,也不需要成為客戶端 bundle 的一部分,簡單地將其重命名為 NewsletterSignup.server.jsx來安全地將其更改為服務(wù)端組件。

          搞定,你可以在最終的 Stackblitz 代碼示例[2] 中查看這個(gè)時(shí)事通訊注冊組件。

          產(chǎn)品常見問題組件

          在下一個(gè)示例中,我們將產(chǎn)品常見問題部分添加到產(chǎn)品頁面。這里的內(nèi)容是靜態(tài)的,對我的在線商店中的每個(gè)產(chǎn)品都是一樣的。來自買家的互動可以展開或收起內(nèi)容。它看起來是這樣的:

          讓我們從一個(gè)共享的ProductFAQs.jsx開始。jsx 組件:

          export?default?function?ProductFAQs()?{
          ??return?(
          ????<ul>
          ??????<li>
          ????????<span>Where?was?this?board?made?span>

          ????????<p>
          ??????????All?our?boards?are?designed?in?Canada?by?our?Hydrogen?design?team.
          ????????p>
          ????????<p>Materials?are?sourced?from?local?manufacturers.p>
          ????????<p>
          ??????????Assembly?is?done?by?our?skilled?team?on?site?in?our?brick?and?mortar
          ??????????shop.
          ????????p>
          ??????li>
          ??????<li>
          ????????<span>What?if?I?don't?like?it?span>
          ????????<p>
          ??????????The?Hydrogen?team?stands?by?their?products.?We?strive?to?delivery?high
          ??????????quality?boards?that?will?last?a?lifetime?and,?importantly,?make?you
          ??????????happy.
          ????????p>
          ????????<p>
          ??????????That?said,?if?you?don't?like?it,?you?can?return?it?to?us?(free?of
          ??????????cost!)?and?we'll?reimburse?you?the?money.?Contact?us?directly?for?more
          ??????????details.
          ????????p>
          ??????li>
          ????ul>
          ??);
          }

          接下來,我們將把它添加到產(chǎn)品頁面。ProductDetails.client 組件用于展示此頁面的主要內(nèi)容,因此很容易把ProductFAQs轉(zhuǎn)換為客戶端組件,這樣 ProductDetails 組件可以直接導(dǎo)入使用它。但是,我們可以通過將 ProductFAQs 傳遞給 product/[handle].server.jsx 頁面來避免這種情況:

          import?ProductFAQs?from?'../../components/ProductFAQs';

          export?default?function?Product({?country?=?{?isoCode:?'US'?}?})?{
          ??//?...
          ??return?(
          ????<Layout>
          ??????<ProductDetails?product={data.product}>
          ????????<ProductFAQs?/>
          ??????ProductDetails>

          ????Layout>
          ??);
          }

          然后更新 ProductDetails組件來使用 children:

          export?default?function?ProductDetails({?product,?children?})?{
          ??//?...

          ??return?(
          ????<>
          ??????<Seo?product={product}?/>
          ??????<Product?product={product}?initialVariantId={initialVariant.id}>
          ????????...
          ??????Product>

          ??????{children}
          ????
          ??);
          }

          接下來,我們想要將客戶端交互部分添加到 ProductFAQs 組件。同樣,我們很容易直接將 ProductFAQ 組件從共享組件轉(zhuǎn)換為客戶端組件,但沒必要。這些交互僅用于展開和收起 FAQ 內(nèi)容,而內(nèi)容本身是硬編碼的,不需要成為客戶端 bundle 的一部分。我們要做的是將客戶端交互提取到一個(gè)專門的客戶端組件Accordion.client.jsx:

          import?{?useState?}?from?'react';

          export?default?function?Accordion({?heading,?children?})?{
          ??const?[open,?setOpen]?=?useState(false);

          ??return?(
          ????<div>
          ??????<div
          ????????onClick={()?=>
          ?{
          ??????????setOpen(!open);
          ????????}}
          ??????>
          ????????<span>{heading}span>

          ????????<span>{open???'-'?:?'+'}span>
          ??????div>
          ??????{open?&&?children}
          ????div>
          ??);
          }

          更新ProductFAQs組件來使用Accordion

          import?Accordion?from?'./Accordion.client';

          export?default?function?ProductFAQs()?{
          ??return?(
          ????<ul>
          ??????<li>
          ????????<Accordion?heading="Where?was?this?board?made?">
          ??????????<>
          ????????????<p>
          ??????????????All?our?boards?are?designed?in?Canada?by?our?Hydrogen?design?team.
          ????????????p>

          ????????????<p>Materials?are?sourced?from?local?manufacturers.p>
          ????????????<p>
          ??????????????Assembly?is?done?by?our?skilled?team?on?site?in?our?brick?and
          ??????????????mortar?shop.
          ????????????p>
          ??????????
          ????????Accordion>
          ??????li>
          ??????<li>
          ????????<Accordion?heading="What?if?I?don't?like?it?">
          ??????????<>
          ????????????<p>
          ??????????????The?Hydrogen?team?stands?by?their?products.?We?strive?to?delivery
          ??????????????high?quality?boards?that?will?last?a?lifetime?and,?importantly,
          ??????????????make?you?happy.
          ????????????p>

          ????????????<p>
          ??????????????That?said,?if?you?don't?like?it,?you?can?return?it?to?us?(free?of
          ??????????????cost!)?and?we'll?reimburse?you?the?money.?Contact?us?directly?for
          ??????????????more?details.
          ????????????p>
          ??????????
          ????????Accordion>
          ??????</li>
          ????l>
          ??);
          }

          此時(shí),不再有理由讓 ProductFAQs 組件保持為共享組件了。所有的客戶端交互都已經(jīng)被提取出來,并且,類似于NewsletterSignup組件,我知道這個(gè)組件永遠(yuǎn)不會被客戶端組件使用?,F(xiàn)在剩下的就是:

          • 重命名 ProductFAQs.jsx 文件為 ProductFAQs.server.jsx

          • 更新 product/[handle].server.jsx 中的 import 聲明

          • 通過 Tailwind 添加一些漂亮的樣式。

          你可以在 Stackblitz 中查看 Product FAQ 代碼[3]

          React Server Components 是一種范式轉(zhuǎn)變,為 RSC 應(yīng)用程序編寫組件可能需要一些時(shí)間來適應(yīng)。當(dāng)你在構(gòu)建時(shí),請記住以下幾點(diǎn):

          • 從共享組件開始。

          • 在特定情況下,將功能提取到客戶端組件中。

          • 如果代碼永遠(yuǎn)不需要或永遠(yuǎn)不應(yīng)該在客戶機(jī)上執(zhí)行,則改寫為服務(wù)端組件。

          享受 coding 吧!

          Cathryn 是 Shopify Checkout 團(tuán)隊(duì)的前端開發(fā)人員,也是 Hydrogen 的創(chuàng)始成員。她在加拿大蒙特利爾遠(yuǎn)程工作。當(dāng)不寫代碼的時(shí)候,她通常會和她的狗玩、做手工或閱讀。

          參考:https://shopify.engineering/react-server-components-best-practices-hydrogen

          • 關(guān)注公眾號后,在首頁:

            回復(fù)指南高級前端、算法學(xué)習(xí)路線,是我自己一路走來的實(shí)踐。
            回復(fù)簡歷,大廠簡歷編寫指南,是我看了上百份簡歷后總結(jié)的心血。
            參考資料

          [1]

          Hydrogen 啟動模板: https://hydrogen.new/

          [2]

          Stackblitz 代碼示例: https://stackblitz.com/edit/shopify-hydrogen-9emcac?file=src%2Fcomponents%2FNewsletterSignup.server.jsx

          [3]

          Product FAQ 代碼: https://stackblitz.com/edit/shopify-hydrogen-9emcac?file=src%2Fcomponents%2FProductFAQs.server.jsx&title=Hydrogen


          瀏覽 99
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  久草国产精品 | 啪啪福利导航 | 欧美亚洲黄色电影免费收看 | 影音先锋一区二区 | 毛片美女视频 |