国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

首頁 web前端 js教程 存在主義的 React 問題和完美的模態(tài)對話框

存在主義的 React 問題和完美的模態(tài)對話框

Jan 03, 2025 am 03:44 AM

Existential React questions and a perfect Modal Dialog

你認(rèn)為React中最複雜的事情是什麼?重新渲染?情境?門戶網(wǎng)站?並行?

不。

React 最困難的部分是它周圍的一切非 React。 「上面列出的那些東西是如何運(yùn)作的?」這個問題的答案很簡單:只需遵循演算法並做筆記即可。結(jié)果將是確定的並且始終相同(如果您正確追蹤)。這只是科學(xué)和事實。

但是「什麼讓元件呢?」或「實作…(某事)的正確方法是什麼?」甚至「我應(yīng)該使用函式庫還是建立自己的解決方案?」這裡唯一正確的答案是「這取決於情況」。它恰好是最沒有幫助的一個。

我想為新文章找到比這更好的東西。但由於這些類型的問題不可能有簡單的答案和通用的解決方案,因此這篇文章更多是我的思考過程的演練,而不是「這就是答案,永遠(yuǎn)這樣做」。希望它仍然有用。

那麼,如何將功能從想法轉(zhuǎn)變?yōu)榭赏度肷a(chǎn)的解決方案呢?讓我們嘗試實作一個簡單的模態(tài)對話框並看看。那有什麼可能是複雜的呢? ?

第 1 步:從最簡單的解決方案開始

讓我們從有時被稱為「尖峰」的東西開始 - 最簡單的實現(xiàn),可以幫助探索潛在的解決方案並收集進(jìn)一步的需求。我知道我正在實現(xiàn)一個模式對話框。假設(shè)我有一個像這樣的漂亮設(shè)計:

Existential React questions and a perfect Modal Dialog

對話方塊基本上是螢?zāi)簧系脑兀?dāng)點擊按鈕之類的內(nèi)容時會出現(xiàn)該元素。這正是我要開始的地方。

export default function Page() {
  const [isOpen, setIsOpen] = useState(false);
  return (
    <>
      <button onClick={() => setIsOpen(true)}>
        Click me
      </button>
      {isOpen ? (
        <div className="dialog">some content</div>
      ) : null}
    </>
  );
}

狀態(tài),一個監(jiān)聽點擊的按鈕,以及當(dāng)狀態(tài)為 true 時顯示的未來對話框。對話框也應(yīng)該有一個“關(guān)閉”操作:

<button
  className="close-button"
  onClick={() => setIsOpen(false)}
>
  Close
</button>

它還有一個「背景」 - 一個可點擊的半透明 div,覆蓋內(nèi)容並在點擊時觸發(fā)模式消失。

<div
  className="backdrop"
  onClick={() => setIsOpen(false)}
></div>

大家在一起:

export default function Page() {
  const [isOpen, setIsOpen] = useState(false);
  return (
    <>
      <button onClick={() => setIsOpen(true)}>
        Click me
      </button>
      {isOpen ? (
        <>
          <div
            className="backdrop"
            onClick={() => setIsOpen(false)}
          ></div>
          <div className="dialog">
            <button
              className="close-button"
              onClick={() => setIsOpen(false)}
            >
              Close
            </button>
          </div>
        </>
      ) : null}
    </>
  );
}

我通常也會儘早添加合適的樣式??吹轿艺趯崿F(xiàn)的功能以與預(yù)期相同的外觀出現(xiàn)在螢?zāi)簧?,這有助於我思考。另外,它還可以通知功能的佈局,這正是此對話方塊將發(fā)生的情況。

讓我們快速為背景添加 CSS - 它沒什麼特別的,只是 div 上的半透明背景,位置固定:佔據(jù)整個螢?zāi)唬?br>

export default function Page() {
  const [isOpen, setIsOpen] = useState(false);
  return (
    <>
      <button onClick={() => setIsOpen(true)}>
        Click me
      </button>
      {isOpen ? (
        <div className="dialog">some content</div>
      ) : null}
    </>
  );
}

該對話框稍微有趣一些,因為它需要放置在螢?zāi)恢虚g。當(dāng)然,CSS 中有 1001 種方法可以實現(xiàn)這一目標(biāo),但我最喜歡的也可能是最簡單的一種是:

<button
  className="close-button"
  onClick={() => setIsOpen(false)}
>
  Close
</button>

我們使用「固定」位置來擺脫佈局約束,新增 50% 的左側(cè)和頂部以將 div 移動到中間位置,然後將其變換回 50%。 left 和 top 將相對於螢?zāi)贿M(jìn)行計算,變換將相對於 div 本身的寬度/高度,因此,無論其寬度或螢?zāi)粚挾热绾?,它都會出現(xiàn)在中間。

此步驟中 CSS 的最後一點是正確設(shè)定對話方塊本身和「關(guān)閉」按鈕的樣式。這裡就不複製貼上了,實際的樣式並不重要,請看一下例子:

第二步:停下來,提出問題並思考

現(xiàn)在我已經(jīng)粗略地實現(xiàn)了該功能,是時候讓它變得「真實」了。為此,我們需要詳細(xì)了解我們到底要解決什麼問題以及為誰解決問題。從技術(shù)上講,我們應(yīng)該明白編碼任何東西之前,所以很多時候,這一步應(yīng)該是第1步。

此對話框是否是原型的一部分,需要盡快實施,向投資者展示一次,然後不再使用?或者它可能是您要在 npm 和開源上發(fā)布的通用庫的一部分?或者它可能是您的 5,000 人組織將使用的設(shè)計系統(tǒng)的一部分?或者它只是您的 3 人小型團(tuán)隊的內(nèi)部工具的一部分,僅此而已?或者,也許您在 TikTok 等公司工作,而此對話方塊將成為僅在行動裝置上可用的網(wǎng)路應(yīng)用程式的一部分?或者您可能在一家只為政府編寫應(yīng)用程式的機(jī)構(gòu)工作?

回答這些問題可以決定下一步編碼的方向。

如果只是一個原型,用一次,可能就已經(jīng)夠了。

如果它要作為庫的一部分開源,它需要有一個非常好的通用 API,世界上任何開發(fā)人員都可以使用和理解,大量的測試和良好的文檔。

作為 5,000 人組織的設(shè)計系統(tǒng)一部分的對話方塊需要遵守組織的設(shè)計準(zhǔn)則,並且可能會限制將哪些外部依賴項帶入儲存庫。因此,您可能需要從頭開始實作許多事情,而不是執(zhí)行 npm install new-fancy-tool。

為政府建立的機(jī)構(gòu)的對話可能需要成為宇宙中最容易訪問且符合法規(guī)的對話。否則,該機(jī)構(gòu)可能會失去政府合約並破產(chǎn)。

等等等等。

出於本文的目的,我們假設(shè)該對話框是現(xiàn)有大型商業(yè)網(wǎng)站當(dāng)前正在進(jìn)行的全新重新設(shè)計的一部分,該網(wǎng)站每天有來自世界各地的數(shù)千名用戶。重新設(shè)計正在進(jìn)行中,我得到的唯一帶有對話框的設(shè)計是這樣的:

Existential React questions and a perfect Modal Dialog

剩下的稍後再說,設(shè)計師們都忙不過來了。此外,我是負(fù)責(zé)重新設(shè)計和維護(hù)網(wǎng)站的永久團(tuán)隊的一員,而不是為單一專案僱用的外部承包商。

在這種情況下,僅憑這張圖片並了解我們公司的目標(biāo)就可以為我提供足夠的資訊來做出合理的假設(shè)並實現(xiàn) 90% 的對話。剩下的10%可以稍後再微調(diào)。

這些是我根據(jù)上述資訊可以做出的假設(shè):

  • 現(xiàn)有網(wǎng)站每天有來自世界各地的數(shù)千名用戶,因此我需要確保該對話框至少可以在大螢?zāi)缓托袆游災(zāi)灰约安煌臑g覽器上運(yùn)行。理想情況下,我需要檢查現(xiàn)有分析才能絕對確定,但這是一個非常安全的選擇。

  • 不只一位開發(fā)人員正在為此編寫程式碼,而且程式碼將保留下來。網(wǎng)站規(guī)模很大,已經(jīng)擁有數(shù)千名用戶;對投資者來說,這不是一個快速的原型。所以,我需要確保程式碼可讀,API有意義,可用且可維護(hù),並且沒有明顯的腳槍。

  • 公司關(guān)心其形象和網(wǎng)站的品質(zhì) - 否則,他們?yōu)槭颤N要重新設(shè)計? (我們假設(shè)這裡有積極的意圖?)。這意味著需要達(dá)到一定的品質(zhì)水平,我需要提前思考並預(yù)測常見場景和邊緣情況,即使它們還不是目前設(shè)計的一部分。

  • 許多使用者可能意味著並非所有人都專門使用滑鼠與網(wǎng)站互動。該對話框還必須可以透過鍵盤互動甚至螢?zāi)婚喿x器等輔助技術(shù)來使用。

  • 現(xiàn)有的大型程式碼庫(記住,這是重新設(shè)計?。┮馕吨铱梢詾榇斯δ軒淼耐獠恳蕾図椏赡艽嬖谙拗?。任何外部依賴都是有代價的,尤其是在大型和舊的程式碼庫中。出於本文的目的,我們假設(shè)我可以使用外部庫,但我需要對此有一個很好的理由。

  • 最後,更多的設(shè)計即將到來,所以我需要從設(shè)計和用戶的角度預(yù)測它會走向何方,並確保程式碼可以儘早處理它。

第 3 步:固化模態(tài)對話框 API

現(xiàn)在我知道了需求並有了合理的猜測,我可以製作實際的對話框組件了。首先,從這段程式碼來看:

export default function Page() {
  const [isOpen, setIsOpen] = useState(false);
  return (
    <>
      <button onClick={() => setIsOpen(true)}>
        Click me
      </button>
      {isOpen ? (
        <div className="dialog">some content</div>
      ) : null}
    </>
  );
}

我絕對需要將對話框部分提取到可重複使用元件中 - 將有大量基於對話框的功能需要實現(xiàn)。

<button
  className="close-button"
  onClick={() => setIsOpen(false)}
>
  Close
</button>

對話方塊將有一個 onClose 屬性 - 當(dāng)按一下「關(guān)閉」按鈕或背景時,它將通知父元件。然後,父元件仍將具有狀態(tài)並呈現(xiàn)對話框,如下所示:

<div
  className="backdrop"
  onClick={() => setIsOpen(false)}
></div>

現(xiàn)在,讓我們再次看看設(shè)計並更多地考慮對話框:

Existential React questions and a perfect Modal Dialog

對話框中顯然會有一些帶有操作按鈕的“頁腳”部分。這些按鈕很可能會有很多變化 - 一個、兩個、三個、左對齊、右對齊、中間有空格等等。此外,此對話框沒有 標(biāo)題 ,但是它非常非常有可能具有某些標(biāo)題的對話框是一種非常常見的模式。這裡絕對會有一個內(nèi)容區(qū)域,其中包含完全隨機(jī)的內(nèi)容 - 從確認(rèn)文本到表格,再到互動體驗,再到?jīng)]有人閱讀的很長的“條款和條件”可滾動文本。

最後是尺寸。設(shè)計中的對話框很小,只是一個確認(rèn)對話框。大表格或長文不適合那裡。因此,考慮到我們在步驟 2 中收集的信息,可以非常安全地假設(shè)對話框的大小需要更改。此時,考慮到設(shè)計師可能有設(shè)計指南,我們可以假設(shè)對話方塊有三種變體:「小」、「中」和「大」。

所有這些意味著我們需要在 ModalDialog 上有 props:頁腳和 header 將只是接受 ReactNode 的常規(guī) props,大小將只是字符串的聯(lián)合,而內(nèi)容區(qū)域作為主要部分將進(jìn)入孩子們:

export default function Page() {
  const [isOpen, setIsOpen] = useState(false);
  return (
    <>
      <button onClick={() => setIsOpen(true)}>
        Click me
      </button>
      {isOpen ? (
        <>
          <div
            className="backdrop"
            onClick={() => setIsOpen(false)}
          ></div>
          <div className="dialog">
            <button
              className="close-button"
              onClick={() => setIsOpen(false)}
            >
              Close
            </button>
          </div>
        </>
      ) : null}
    </>
  );
}

我們將使用來自道具的附加 className 來控制對話框的大小。但在現(xiàn)實生活中,它將很大程度上取決於儲存庫中使用的樣式解決方案。

然而,在這個變體中,對話框太靈活了 - 幾乎任何東西都可以去任何地方。例如,在頁腳中,大多數(shù)時候,我們只需要一兩個按鈕,僅此而已。這些按鈕必須一致地排列在整個網(wǎng)站的各處。我們需要一個包裝器來對齊它們:

.backdrop {
  background: rgba(0, 0, 0, 0.3);
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

與內(nèi)容相同 - 至少,它需要一些周圍的填充和滾動能力。標(biāo)題可能需要一些文字樣式。於是版面就變成這樣:

export default function Page() {
  const [isOpen, setIsOpen] = useState(false);
  return (
    <>
      <button onClick={() => setIsOpen(true)}>
        Click me
      </button>
      {isOpen ? (
        <div className="dialog">some content</div>
      ) : null}
    </>
  );
}

但不幸的是,我們無法保證這一點。在某些時候,很可能有人希望在頁腳中添加按鈕以外的更多內(nèi)容。或某些對話方塊需要在已售背景上有標(biāo)題。或者有時,內(nèi)容不需要填充。

我在這裡要指出的是,有一天我們需要能夠設(shè)計頁首/內(nèi)容/頁尾部分的樣式。而且可能比預(yù)期早。

當(dāng)然,我們可以只使用 props 傳遞該配置,並使用 headerClassName、contentClassName 和 footerClassName 等 props。實際上,對於某些情況來說,這可能沒問題。但對於像重新設(shè)計的漂亮對話框這樣的東西,我們可以做得更好。

解決這個問題的一個非常巧妙的方法是將我們的頁眉/內(nèi)容/頁腳提取到它們自己的組件中,如下所示:

<button
  className="close-button"
  onClick={() => setIsOpen(false)}
>
  Close
</button>

並將 ModalDialog 程式碼還原為沒有包裝器的程式碼:

<div
  className="backdrop"
  onClick={() => setIsOpen(false)}
></div>

這樣,在父應(yīng)用程式中,如果我想要對話框部分的預(yù)設(shè)設(shè)計,我會使用這些微小的元件:

export default function Page() {
  const [isOpen, setIsOpen] = useState(false);
  return (
    <>
      <button onClick={() => setIsOpen(true)}>
        Click me
      </button>
      {isOpen ? (
        <>
          <div
            className="backdrop"
            onClick={() => setIsOpen(false)}
          ></div>
          <div className="dialog">
            <button
              className="close-button"
              onClick={() => setIsOpen(false)}
            >
              Close
            </button>
          </div>
        </>
      ) : null}
    </>
  );
}

如果我想要完全自訂的東西,我會實作一個具有自己的自訂樣式的新元件,而不會弄亂 ModalDialog 本身:

.backdrop {
  background: rgba(0, 0, 0, 0.3);
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

就此而言,我甚至不再需要頁首和頁尾道具。我可以將 DialogHeader 和 DialogFooter 傳遞給子級,進(jìn)一步簡化 ModalDialog,並擁有更好的 API,具有相同程度的靈活性,同時在各處都有一致的設(shè)計。

父組件將如下圖所示:

.dialog {
  position: fixed;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}

對話框的 API 將如下所示:

export default function Page() {
  const [isOpen, setIsOpen] = useState(false);
  return (
    <>
      <button onClick={() => setIsOpen(true)}>
        Click me
      </button>
      {isOpen ? (
        <>
          <div
            className="backdrop"
            onClick={() => setIsOpen(false)}
          ></div>
          <div className="dialog">
            <button
              className="close-button"
              onClick={() => setIsOpen(false)}
            >
              Close
            </button>
          </div>
        </>
      ) : null}
    </>
  );
}

到目前為止我對此非常滿意。它足夠靈活,可以以設(shè)計可能需要的任何方式進(jìn)行擴(kuò)展,但它也足夠清晰和合理,可以輕鬆地在整個應(yīng)用程式中實現(xiàn)一致的 UI。

這是可以使用的實例:

第四步:效能和重新渲染

現(xiàn)在 Modal 的 API 已經(jīng)夠好了,是時候解決我實現(xiàn)的明顯的腳槍問題了。如果你讀夠了我的文章,你可能已經(jīng)大聲尖叫,「你在做什麼???重新渲染!!」最後十分鐘?當(dāng)然,你是對的:

const ModalDialog = ({ onClose }) => {
  return (
    <>
      <div className="backdrop" onClick={onClose}></div>
      <div className="dialog">
        <button className="close-button" onClick={onClose}>
          Close
        </button>
      </div>
    </>
  );
};

這裡的Page組件是有狀態(tài)的。每次模式開啟或關(guān)閉時,狀態(tài)都會發(fā)生變化,並且會導(dǎo)致整個元件及其內(nèi)部所有內(nèi)容的重新渲染。是的,“過早的優(yōu)化是萬惡之源”,是的,在實際測量性能之前不要優(yōu)化性能,在這種情況下,我們可以安全地忽略傳統(tǒng)觀點。

有兩個原因。首先,我知道一個事實是,整個應(yīng)用程式中會分散很多模式。這不是一個沒有人會使用的一次性隱藏功能。因此,有人將狀態(tài)放置在不應(yīng)該使用這樣的 API 的地方的可能性非常高。其次,從一開始就不需要花費太多時間和精力來防止重新渲染問題的發(fā)生。只要1分鐘的努力,我們根本不需要考慮這裡的效能。

我們需要做的就是封裝狀態(tài)並引入「不受控組件」的想法:

export default function Page() {
  const [isOpen, setIsOpen] = useState(false);
  return (
    <>
      <button onClick={() => setIsOpen(true)}>
        Click me
      </button>
      {isOpen ? (
        <div className="dialog">some content</div>
      ) : null}
    </>
  );
}

BaseModalDialog 與我們之前的對話框完全相同,我只是重命名了它。

然後傳遞一個應(yīng)該觸發(fā)對話框的元件作為觸發(fā)道具:

<button
  className="close-button"
  onClick={() => setIsOpen(false)}
>
  Close
</button>

頁面元件將如下所示:

<div
  className="backdrop"
  onClick={() => setIsOpen(false)}
></div>

頁面內(nèi)不再有狀態(tài),不再有潛在危險的重新渲染。

這樣的 API 應(yīng)該涵蓋 95% 的用例,因為大多數(shù)時候,使用者需要點擊某些內(nèi)容才能顯示對話框。在極少數(shù)情況下,當(dāng)對話方塊需要獨立顯示時,例如,在捷徑上或作為入門的一部分,我仍然可以使用 BaseModalDialog 並手動處理狀態(tài)。

第 5 步:處理邊緣情況和可訪問性

從 React 的角度來看,ModalDialog 元件的 API 非??煽?,但工作還遠(yuǎn)遠(yuǎn)沒有完成??紤]到我在步驟 2 中收集的必備條件,我還需要解決更多問題。

問題 1:我將觸發(fā)器包裝到一個額外的跨度中 - 在某些情況下,這可能會破壞頁面的佈局。我需要以某種方式去除包裝紙。

問題 2:如果我在建立新堆疊上下文的元素內(nèi)渲染對話框,則模式將出現(xiàn)在某些元素下方。我需要在 Portal 內(nèi)渲染它,而不是像我現(xiàn)在一樣直接在佈局內(nèi)渲染。

問題 3:目前鍵盤存取非常糟糕。當(dāng)正確實現(xiàn)的模式對話方塊打開時,焦點應(yīng)該跳到裡面。當(dāng)它關(guān)閉時 - 焦點應(yīng)該會回到觸發(fā)對話方塊的元素。當(dāng)對話方塊打開時,焦點應(yīng)該被「困」在裡面,而外面的元素不應(yīng)該是可聚焦的。按 ESC 按鈕應(yīng)關(guān)閉該對話方塊。目前這些都還沒實現(xiàn)。

問題 1 和 2 有點煩人,但可以相對快速地解決。然而,手動完成第 3 個問題是一件非常痛苦的事情。另外,這肯定是一個已解決的問題 - 每個地方的每個對話框都需要此功能。

「我自己做的巨大痛苦」「看起來肯定是一個已解決的問題」的組合是我尋找現(xiàn)有庫的地方。

考慮到我已經(jīng)完成的所有前期工作,現(xiàn)在選擇合適的就很容易了。

我可以使用任何現(xiàn)有的 UI 元件庫,例如 Ant Design 或 Material UI,並使用其中的對話框。但如果重新設(shè)計不使用它們,將他們的設(shè)計調(diào)整為我需要的,會帶來比他們解決的更多的痛苦。所以對於這種情況,立即否定。

我可以使用「無頭」UI 函式庫之一,例如 Radix 或 React Aria。它們實現(xiàn)了狀態(tài)和觸發(fā)器等功能以及所有可訪問性,但將設(shè)計留給了消費者。在查看他們的 API 時,我需要仔細(xì)檢查它們是否允許我控制對話框的狀態(tài),如果我確實需要它來手動觸發(fā)對話框(他們確實這樣做)。

如果因為某些原因,我無法使用無頭函式庫,我至少會嘗試使用處理焦點陷阱功能的函式庫。

為了本文的目的,我們假設(shè)我可以帶任何我想要的函式庫。在這種情況下,我將使用 Radix - 它非常易於使用,並且對話框的 API 看起來與我已經(jīng)實現(xiàn)的非常相似,因此重構(gòu)應(yīng)該是輕而易舉的。

我們需要稍微改變一下對話框本身的 API:

export default function Page() {
  const [isOpen, setIsOpen] = useState(false);
  return (
    <>
      <button onClick={() => setIsOpen(true)}>
        Click me
      </button>
      {isOpen ? (
        <div className="dialog">some content</div>
      ) : null}
    </>
  );
}

跟我以前的幾乎一樣。只是,我沒有使用 div,而是使用 Radix 原語。

不受控制的對話框用法根本沒有改變:

<button
  className="close-button"
  onClick={() => setIsOpen(false)}
>
  Close
</button>

受控對話框略有變化 - 我需要將道具傳遞給它而不是條件渲染:

<div
  className="backdrop"
  onClick={() => setIsOpen(false)}
></div>

查看下面的範(fàn)例並嘗試使用鍵盤進(jìn)行導(dǎo)航。一切都按照我的需要進(jìn)行,這有多酷?

作為獎勵,Radix 還可以處理 Portal 問題,並且它不會將觸發(fā)器包裝在一個跨度中。我不再需要解決邊緣情況,所以我可以繼續(xù)最後一步。

第6步:最後拋光

該功能還沒完成! ?該對話框現(xiàn)在看起來和感覺都相當(dāng)可靠,因此現(xiàn)階段我不會對其實現(xiàn)進(jìn)行任何重大更改。但對於我正在解決的用例,它仍然需要一些東西才能被認(rèn)為是「完美」對話框。

One:設(shè)計師要求我做的第一件事(如果他們還沒做的話)就是在對話框打開時添加一個微妙的動畫。需要預(yù)見它並記住如何在 React 中製作動畫。

兩個:我需要向?qū)υ捒蛱砑幼畲髮挾群妥畲蟾叨龋员阍谛∥災(zāi)簧纤匀豢雌饋聿诲e。想想它在大螢?zāi)簧系臉幼印?

:我需要與設(shè)計師討論對話框在行動裝置上的行為方式。他們很可能會要求我將其做成一個滑入式面板,無論對話框的大小如何,它都會佔據(jù)大部分螢?zāi)弧?

四個:我需要至少引入 DialogTitle 和 DialogDescription 元件 - Radix 會要求將它們用於輔助功能。

:測驗!該對話方塊將保留下來並由其他人維護(hù),因此在這種情況下測試幾乎是強(qiáng)制性的。

也許還有很多我現(xiàn)在忘記的小事情,稍後會出現(xiàn)。更不用說實現(xiàn)對話框內(nèi)容的實際設(shè)計了。

還有一些想法

如果將上面的“對話框”替換為“SomeNewFeature”,這或多或少是我用來實現(xiàn)幾乎所有新功能的演算法。

解決方案的快速「峰值」→收集功能需求→使其工作→使其高效能→使其完整→使其完美。

對於像實際對話框這樣的東西,我已經(jīng)實現(xiàn)了數(shù)百次,我會在 10 秒內(nèi)在腦海中完成第一步,然後立即從步驟 2 開始。

對於非常複雜和未知的事情,第 1 步可能會更長,並且涉及立即探索不同的解決方案和函式庫。

一些不完全未知的東西,只是“我們需要做的常規(guī)功能”,可能會跳過步驟 1,因為可能沒有什麼可探索的。

很多時候,尤其是在「敏捷」環(huán)境中,它更像是螺旋而不是直線,需求是增量提供的並且經(jīng)常變化,我們會定期返回前兩個步驟。


希望這類文章有用! ??如果您想要更多這樣的內(nèi)容或更喜歡通常的“事情如何運(yùn)作”的內(nèi)容,請告訴我。

並期待聽到你們所有人的腦中這個過程有何不同?


最初發(fā)佈於 https://www.developerway.com。網(wǎng)站還有更多這樣的文章嗎?

看看《Advanced React》一書,將您的 React 知識提升到一個新的水平。

訂閱電子報、在 LinkedIn 上聯(lián)繫或在 Twitter 上關(guān)注,以便在下一篇文章發(fā)佈時立即收到通知。


順便說一句,最後一件事:如果您很快就要開始一個新項目,並且沒有設(shè)計師,也沒有時間來完善所描述的設(shè)計體驗- 我最近花了幾個小時(又幾個小時)來實作一個新的專案本例的UI 元件庫。它具有可複製貼上的組件和常見模式、Radix 和 Tailwind、深色模式、可訪問性以及開箱即用的行動支援。包括上面完美的模態(tài)對話框! ?

試試看:https://www.buckets-ui.com/

Existential React questions and a perfect Modal Dialog

以上是存在主義的 React 問題和完美的模態(tài)對話框的詳細(xì)內(nèi)容。更多資訊請關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本網(wǎng)站聲明
本文內(nèi)容由網(wǎng)友自願投稿,版權(quán)歸原作者所有。本站不承擔(dān)相應(yīng)的法律責(zé)任。如發(fā)現(xiàn)涉嫌抄襲或侵權(quán)的內(nèi)容,請聯(lián)絡(luò)admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅(qū)動的應(yīng)用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強(qiáng)大的PHP整合開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

Java vs. JavaScript:清除混亂 Java vs. JavaScript:清除混亂 Jun 20, 2025 am 12:27 AM

Java和JavaScript是不同的編程語言,各自適用於不同的應(yīng)用場景。 Java用於大型企業(yè)和移動應(yīng)用開發(fā),而JavaScript主要用於網(wǎng)頁開發(fā)。

JavaScript評論:簡短說明 JavaScript評論:簡短說明 Jun 19, 2025 am 12:40 AM

JavascriptconcommentsenceenceEncorenceEnterential gransimenting,reading and guidingCodeeXecution.1)單inecommentsareusedforquickexplanations.2)多l(xiāng)inecommentsexplaincomplexlogicorprovideDocumentation.3)

如何在JS中與日期和時間合作? 如何在JS中與日期和時間合作? Jul 01, 2025 am 01:27 AM

JavaScript中的日期和時間處理需注意以下幾點:1.創(chuàng)建Date對像有多種方式,推薦使用ISO格式字符串以保證兼容性;2.獲取和設(shè)置時間信息可用get和set方法,注意月份從0開始;3.手動格式化日期需拼接字符串,也可使用第三方庫;4.處理時區(qū)問題建議使用支持時區(qū)的庫,如Luxon。掌握這些要點能有效避免常見錯誤。

為什麼要將標(biāo)籤放在的底部? 為什麼要將標(biāo)籤放在的底部? Jul 02, 2025 am 01:22 AM

PlacingtagsatthebottomofablogpostorwebpageservespracticalpurposesforSEO,userexperience,anddesign.1.IthelpswithSEObyallowingsearchenginestoaccesskeyword-relevanttagswithoutclutteringthemaincontent.2.Itimprovesuserexperiencebykeepingthefocusonthearticl

JavaScript與Java:開發(fā)人員的全面比較 JavaScript與Java:開發(fā)人員的全面比較 Jun 20, 2025 am 12:21 AM

JavaScriptIspreferredforredforwebdevelverment,而Javaisbetterforlarge-ScalebackendsystystemsandSandAndRoidApps.1)JavascriptexcelcelsincreatingInteractiveWebexperienceswebexperienceswithitswithitsdynamicnnamicnnamicnnamicnnamicnemicnemicnemicnemicnemicnemicnemicnemicnddommanipulation.2)

JavaScript:探索用於高效編碼的數(shù)據(jù)類型 JavaScript:探索用於高效編碼的數(shù)據(jù)類型 Jun 20, 2025 am 12:46 AM

javascripthassevenfundaMentalDatatypes:數(shù)字,弦,布爾值,未定義,null,object和symbol.1)numberSeadUble-eaduble-ecisionFormat,forwidevaluerangesbutbecautious.2)

什麼是在DOM中冒泡和捕獲的事件? 什麼是在DOM中冒泡和捕獲的事件? Jul 02, 2025 am 01:19 AM

事件捕獲和冒泡是DOM中事件傳播的兩個階段,捕獲是從頂層向下到目標(biāo)元素,冒泡是從目標(biāo)元素向上傳播到頂層。 1.事件捕獲通過addEventListener的useCapture參數(shù)設(shè)為true實現(xiàn);2.事件冒泡是默認(rèn)行為,useCapture設(shè)為false或省略;3.可使用event.stopPropagation()阻止事件傳播;4.冒泡支持事件委託,提高動態(tài)內(nèi)容處理效率;5.捕獲可用於提前攔截事件,如日誌記錄或錯誤處理。了解這兩個階段有助於精確控制JavaScript響應(yīng)用戶操作的時機(jī)和方式。

Java和JavaScript有什麼區(qū)別? Java和JavaScript有什麼區(qū)別? Jun 17, 2025 am 09:17 AM

Java和JavaScript是不同的編程語言。 1.Java是靜態(tài)類型、編譯型語言,適用於企業(yè)應(yīng)用和大型系統(tǒng)。 2.JavaScript是動態(tài)類型、解釋型語言,主要用於網(wǎng)頁交互和前端開發(fā)。

See all articles