」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 前端開發 + 資料結構與演算法:DSA 如何為您的 React 應用程式提供動力 ⚡

前端開發 + 資料結構與演算法:DSA 如何為您的 React 應用程式提供動力 ⚡

發佈於2024-11-03
瀏覽:991

专注于前端的面试通常根本不关心 DSA。

对于我们这些记得在学校/大学学习过 DSA 的人来说,所有的例子都感觉纯粹是算法(有充分的理由),但几乎没有任何例子或指导来说明我们每天使用的产品如何利用这个概念。

“我需要这个吗?”
你已经问过很多次这个问题了,不是吗? ?

以下是您今天可以在 React 应用程序中利用的一些数据结构! ?

目录

  1. 介绍
  2. 数组:状态管理的首选
  3. 对象和哈希图:标准化数据存储以提高效率
  4. 双向链表:使用上下文导航
  5. 堆栈:具有不可变行为的撤消/重做功能
  6. 队列:管理顺序 API 调用
  7. 树:渲染递归组件
  8. 图表:构建复杂的数据关系和导航
  9. 结论

相关阅读:

1. 数组?:状态管理的首选

数组在 React 中无处不在。如果您需要帮助了解 .map() 或 .filter() 的工作原理,您可能会太早看到这篇文章了!但不用担心,一旦您熟悉了这些数组方法,您就会发现它们对于渲染列表、管理组件状态和转换数据是多么重要。

2. 对象和哈希映射?️:标准化数据存储以提高效率

在 React 应用程序中,当您处理大量实体(例如用户或帖子)时,将数据规范化为对象(哈希图)可以使读取和更新更加高效。您无需使用深层嵌套结构,而是通过 ID 映射实体。

示例从具有 ID 的规范化存储中读取

const postsById = {
  1: { id: 1, title: 'First Post', content: 'Content of first post' },
  2: { id: 2, title: 'Second Post', content: 'Content of second post' }
};

const postIds = [1, 2];

function PostList() {
  return (
    
{postIds.map(id => ( ))}
); } function Post({ post }) { return (

{post.title}

{post.content}

); }

这种模式可以实现高效的数据访问,特别是对于需要快速更新或读取而无需重新渲染整个集合的大型数据集。

3. 双向链表?:带上下文的导航

当您需要上一个和下一个元素的上下文时,双向链表非常有用 - 想象一下导航照片库,其中每个图像都显示其相邻图像以供参考。我们不使用索引,而是将当前节点直接存储在组件状态中。

示例用于在具有上下文的元素之间导航的双向链表

class Node {
  constructor(value) {
    this.value = value;
    this.next = null;
    this.prev = null;
  }
}

class DoublyLinkedList {
  constructor() {
    this.head = null;
    this.tail = null;
  }

  add(value) {
    const newNode = new Node(value);
    if (!this.head) {
      this.head = newNode;
      this.tail = newNode;
    } else {
      this.tail.next = newNode;
      newNode.prev = this.tail;
      this.tail = newNode;
    }
  }
}

const imageList = new DoublyLinkedList();
imageList.add({ id: 1, src: 'image1.jpg', alt: 'First Image' });
imageList.add({ id: 2, src: 'image2.jpg', alt: 'Second Image' });
imageList.add({ id: 3, src: 'image3.jpg', alt: 'Third Image' });

function Gallery() {
  const [currentNode, setCurrentNode] = useState(imageList.head);

  return (
    
{currentNode.prev && ( {currentNode.prev.value.alt} )} {currentNode.value.alt} {currentNode.next && ( {currentNode.next.value.alt} )}
); }

在此 React 组件中:

  • 当前节点存储在状态中,并且UI根据是否有上一个或下一个节点进行更新。
  • 这些按钮使用户能够向前和向后导航列表,如果没有更多节点可移动到,则禁用。
  • 此结构通过周围元素的上下文模拟实时导航,通常用于轮播、媒体库或播放列表等 UI 组件中。

4. Stacks ?:具有不可变行为的撤消/重做功能

堆栈允许您使用后进先出 (LIFO) 逻辑有效地管理撤消/重做操作。通过使用不可变操作(concat、slice),我们可以确保状态保持不变。

示例使用不可变的推送和弹出撤消/重做

const [undoStack, setUndoStack] = useState([]);
const [redoStack, setRedoStack] = useState([]);
const [formState, setFormState] = useState({ name: '', email: '' });

const updateForm = (newState) => {
  setUndoStack(prev => prev.concat([formState]));  // Immutable push
  setRedoStack([]);  // Clear redo stack
  setFormState(newState);
};

const undo = () => {
  if (undoStack.length > 0) {
    const lastState = undoStack.at(-1);
    setUndoStack(prev => prev.slice(0, -1));  // Immutable pop
    setRedoStack(prev => prev.concat([formState]));  // Move current state to redo
    setFormState(lastState);
  }
};

const redo = () => {
  if (redoStack.length > 0) {
    const lastRedo = redoStack.at(-1);
    setRedoStack(prev => prev.slice(0, -1));  // Immutable pop
    setUndoStack(prev => prev.concat([formState]));  // Push current state to undo
    setFormState(lastRedo);
  }
};

5. 队列?:管理顺序 API 调用

队列以先进先出 (FIFO) 方式运行,非常适合确保以正确的顺序处理 API 调用或通知等任务。

示例API 调用排队

const [apiQueue, setApiQueue] = useState([]);

const enqueueApiCall = (apiCall) => {
  setApiQueue(prevQueue => prevQueue.concat([apiCall]));  // Immutable push
};

const processQueue = () => {
  if (apiQueue.length > 0) {
    const [nextCall, ...restQueue] = apiQueue;
    nextCall().finally(() => setApiQueue(restQueue));  // Immutable pop
  }
};

6. 树?:渲染递归组件

在处理嵌套组件时,React 中通常会使用树注释线程文件夹结构菜单

示例递归渲染评论树

const commentTree = {
  id: 1,
  text: "First comment",
  children: [
    { id: 2, text: "Reply to first comment", children: [] },
    { id: 3, text: "Another reply", children: [{ id: 4, text: "Nested reply" }] }
  ]
};

function Comment({ comment }) {
  return (
    

{comment.text}

{comment.children?.map(child => (
))}
); }

另一篇可能与您相关的热门帖子:

7. 图表?:构建复杂的数据关系和导航

示例1多个视图之间的路由
您可以将页面之间的路线表示为图表,从而确保 SPA 中灵活的导航路径。

const routesGraph = {
  home: ['about', 'contact'],
  about: ['home', 'team'],
  contact: ['home'],
};

function navigate(currentRoute, targetRoute) {
  if (routesGraph[currentRoute].includes(targetRoute)) {
    console.log(`Navigating from ${currentRoute} to ${targetRoute}`);
  } else {
    console.log(`Invalid route from ${currentRoute} to ${targetRoute}`);
  }
}

示例2用户关系建模
图表非常适合建模社交联系或多个实体互连的任何类型的关系。

const usersGraph = {
  user1: ['user2', 'user3'],
  user2: ['user1', 'user4'],
  user3: ['user1'],
  user4: ['user2']
};

function findConnections(userId) {
  return usersGraph[userId] || [];
}

console.log(findConnections('user1'));  // Outputs: ['user2', 'user3']

注意:我们使用图表来显示中间件中审阅者的依赖关系。

TL;DR——学校的教训得到了回报

这些 DSA 类在当时可能感觉很抽象,但数据结构正在为你周围的 React 世界提供动力。

对象、堆栈、队列、链表、树和图不仅仅是理论——它们是您每天构建的干净、高效和可扩展应用程序的支柱。

因此,下次您管理队列中的状态或处理复杂的 UI 逻辑时,请记住:您从学校起就一直在接受这方面的培训。 ?

让我知道您最常使用哪些数据结构!

版本聲明 本文轉載於:https://dev.to/jayantbh/frontend-dev-data-structures-algorithms-how-dsa-can-power-your-react-app-491a?1如有侵犯,請聯絡study_golang@163 .com刪除
最新教學 更多>
  • 如何在單擊按鈕時列印特定的 HTML 內容而不列印整個頁面?
    如何在單擊按鈕時列印特定的 HTML 內容而不列印整個頁面?
    在按鈕點擊時列印特定的HTML 內容而不包括完整網頁在使用者點擊按鈕時僅列印特定的HTML內容可以透過多種方式實現方式。一種方法是建立一個隱藏的 div 元素來保存所需的 HTML。為了列印目的,該 div 的顯示屬性應設定為“print”,而為了螢幕顯示,其顯示值應保持“none”。頁面上的其他元...
    程式設計 發佈於2024-11-05
  • 尋找經濟實惠的同日格蘭尼公寓(附 Pillar Build Granny Flats)
    尋找經濟實惠的同日格蘭尼公寓(附 Pillar Build Granny Flats)
    在 Pillar Build Granny Flats,我們為您提供祖母屋解決方案的精英服務,滿足您的獨特需求。無論是房主、承包商還是投資者,我們都可以幫助您在當天購買後院公寓,效果非常好,為您節省寶貴的時間,而且不用說,預算也很實惠。我們的祖母房建造者將在每一步工作,以確保您的專案以最精確和細心的...
    程式設計 發佈於2024-11-05
  • 如何使用 botoith Google Colab 和 AWS 集成
    如何使用 botoith Google Colab 和 AWS 集成
    您有沒有想過,在實施AWS Lambda時,想要一一確認程式碼的運作情況? 您可能認為在 AWS 控制台上實施很痛苦,因為您必須執行 Lambda 函數並且每次都會產生成本。 因此,我將向您展示您的擔憂的解決方案。 它是透過 Google Colab 和 AWS 整合實現的。 步驟如下: ...
    程式設計 發佈於2024-11-05
  • (高效能 Web 應用程式的要求
    (高效能 Web 應用程式的要求
    “高性能网络应用程序”或“前端”到底是什么? 自从 Internet Explorer 时代衰落以来,JavaScript 生态系统变得越来越强大,“前端”一词已成为高性能、现代 Web 客户端的代名词。这个“前端”世界的核心是 React。事实上,在前端开发中不使用 React 常常会让一个人看...
    程式設計 發佈於2024-11-05
  • 如何將單一輸入欄位設定為分區輸入?
    如何將單一輸入欄位設定為分區輸入?
    將輸入欄位設為分區輸入有多種方法可用於建立一系列分區輸入欄位。一種方法利用「字母間距」來分隔單一輸入欄位內的字元。此外,「background-image」和「border-bottom」樣式可以進一步增強多個輸入欄位的錯覺。 CSS Snippet以下 CSS 程式碼示範如何建立所需的效果:#pa...
    程式設計 發佈於2024-11-05
  • 用 Go 建構一個簡單的負載平衡器
    用 Go 建構一個簡單的負載平衡器
    负载均衡器在现代软件开发中至关重要。如果您曾经想知道如何在多个服务器之间分配请求,或者为什么某些网站即使在流量大的情况下也感觉更快,答案通常在于高效的负载平衡。 在这篇文章中,我们将使用 Go 中的循环算法构建一个简单的应用程序负载均衡器。这篇文章的目的是逐步了解负载均衡器的工作原理。 ...
    程式設計 發佈於2024-11-05
  • 如何以超連結方式開啟本機目錄?
    如何以超連結方式開啟本機目錄?
    透過超連結導航本地目錄嘗試在連結互動時啟動本地目錄視圖時,您可能會遇到限制。然而,有一個解決方案可以解決這個問題,並且可以在各種瀏覽器之間無縫運作。 實作方法因為從HTML 頁面直接開啟路徑或啟動瀏覽器是由於安全原因受到限制,更可行的方法是提供可下載的連結( .URL 或.LNK)。 建議路徑:.U...
    程式設計 發佈於2024-11-05
  • 為什麼 Makefile 會拋出 Go 指令的權限被拒絕錯誤?
    為什麼 Makefile 會拋出 Go 指令的權限被拒絕錯誤?
    在執行Go 時Makefile 中出現權限被拒絕錯誤透過Makefile 執行Go 指令時可能會遇到「權限被拒絕」錯誤,即使你可以直接執行它們。這種差異是由於 GNU make 中的問題引起的。 原因:當您的 PATH 上有一個目錄包含名為“go.gnu”的子目錄時,就會出現此錯誤。 ”例如,如果您...
    程式設計 發佈於2024-11-05
  • parseInt 函數中 Radix 參數的意義是什麼?
    parseInt 函數中 Radix 參數的意義是什麼?
    parseInt 函數中 Radix 的作用parseInt 函數將字串轉換為整數。然而,它並不總是採用以 10 為基數的數字系統。若要指定所需的基數,請使用基數參數。 理解基數基數是指單一數字表示的值的數量。例如,十六進制的基數為 16,八進制的基數為 8,二進制的基數為 2。 為什麼要用基數? ...
    程式設計 發佈於2024-11-05
  • 如何使用 JavaScript 將連結保留在同一選項卡中?
    如何使用 JavaScript 將連結保留在同一選項卡中?
    在同一分頁和視窗中導覽連結您可能會遇到想要在同一視窗和分頁中開啟連結的情況作為當前頁面。但是,使用 window.open 函數通常會導致在新分頁中開啟連結。為了解決這個問題,您可以使用name 屬性,如下所示:window.open("https://www.youraddress.co...
    程式設計 發佈於2024-11-05
  • 如何解決Python中的循環依賴?
    如何解決Python中的循環依賴?
    Python 中的循環依賴使用 Python 模組時遇到循環依賴可能是一個令人沮喪的問題。在這個特定場景中,我們有兩個文件,node.py 和 path.py,分別包含 Node 和 Path 類別。 最初,path.py 使用 from node.py import * 導入 node.py。但是...
    程式設計 發佈於2024-11-05
  • MariaDB 與 MySQL:開發人員需要了解什麼
    MariaDB 與 MySQL:開發人員需要了解什麼
    MariaDB 和 MySQL 是著名的開源 RDBMS,但儘管它們有著共同的歷史,但它們在功能和效能方面卻有所不同。本文快速強調了主要差異,幫助開發人員決定哪個資料庫最適合他們的需求。 差異和範例 儲存引擎,MariaDB 對 Aria 和 MyRocks 等引擎的擴充支援提供了...
    程式設計 發佈於2024-11-05
  • 為什麼我的 Goroutine 遞增變數會產生意外的結果?
    為什麼我的 Goroutine 遞增變數會產生意外的結果?
    這是編譯器最佳化的結果嗎? 在此程式碼片段中,啟動了一個 goroutine 並重複遞增變數 i:package main import "time" func main() { i := 1 go func() { for { ...
    程式設計 發佈於2024-11-05
  • 利用 AI 快速學習 Node.js - 第 4 天
    利用 AI 快速學習 Node.js - 第 4 天
    今天,借助ChatGPT繼續學習Node.js,重點是非同步程式設計。這是 Node.js 中最重要的概念之一,我很高興能夠開始掌握它。 理論 在 Node.js 中,非同步程式設計因其非阻塞、事件驅動的架構而至關重要。這意味著文件讀取、資料庫查詢或網路請求等操作在等待結果時不會阻塞其他程式碼的執...
    程式設計 發佈於2024-11-05
  • Java 可以定義帶有嵌入引號的字串而不轉義嗎?
    Java 可以定義帶有嵌入引號的字串而不轉義嗎?
    揭開Java 使用嵌入式引號定義字串的替代方法在Java 中處理字串時,您常常會在文字中遇到大量引號,導致繁瑣的轉義和可讀性挑戰。雖然其他語言提供了處理這種情況的語法,但 Java 缺乏類似的選項。 問題: Java 是否提供了另一種方法來定義帶有嵌入引號的字串而不訴諸轉義? 答案: 雖然Java ...
    程式設計 發佈於2024-11-05

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3