„Wenn ein Arbeiter seine Arbeit gut machen will, muss er zuerst seine Werkzeuge schärfen.“ – Konfuzius, „Die Gespräche des Konfuzius. Lu Linggong“
Titelseite > Programmierung > Frontend-Entwicklung + Datenstrukturen und Algorithmen: Wie DSA Ihre React-App unterstützen kann ⚡

Frontend-Entwicklung + Datenstrukturen und Algorithmen: Wie DSA Ihre React-App unterstützen kann ⚡

Veröffentlicht am 03.11.2024
Durchsuche:218

Frontend-fokussierte Interviews kümmern sich oft überhaupt nicht um DSA.

Und für diejenigen von uns, die sich erinnern, DSA in der Schule/Universität studiert zu haben, fühlten sich alle Beispiele rein algorithmisch an (aus gutem Grund), aber es gab kaum Beispiele oder Anleitungen dazu, wie die Produkte, die wir täglich verwenden, dieses Konzept nutzen.

„Werde ich das jemals brauchen?“
Das haben Sie schon oft gefragt, nicht wahr? ?

Hier sind einige Datenstrukturen, die Sie noch heute in Ihrer React-App nutzen können! ?

Inhaltsverzeichnis

  1. Einführung
  2. Arrays: Ihre Anlaufstelle für die Zustandsverwaltung
  3. Objekte und Hash-Maps: Normalisierter Datenspeicher für Effizienz
  4. Doppelt verknüpfte Listen: Navigation mit Kontext
  5. Stacks: Rückgängig-/Wiederholen-Funktionalität mit unveränderlichem Verhalten
  6. Warteschlangen: Sequentielle API-Aufrufe verwalten
  7. Bäume: Rekursive Komponenten rendern
  8. Grafiken: Aufbau komplexer Datenbeziehungen und Navigation
  9. Abschluss

Verwandte Lektüre:

1. Arrays?: Ihre Anlaufstelle für die Zustandsverwaltung

Arrays gibt es überall in React. Wenn Sie Hilfe benötigen, um zu verstehen, wie .map() oder .filter() funktionieren, sehen Sie diesen Beitrag wahrscheinlich etwas zu früh! Aber keine Sorge – sobald Sie sich mit diesen Array-Methoden vertraut gemacht haben, werden Sie erkennen, wie wichtig sie für die Darstellung von Listen, die Verwaltung von Komponentenzuständen und die Transformation von Daten sind.

2. Objekte und Hash-Maps ?️: Normalisierter Datenspeicher für Effizienz

Wenn Sie in einer React-App mit einer großen Sammlung von Entitäten wie Benutzern oder Beiträgen arbeiten, kann die Normalisierung Ihrer Daten in Objekte (Hash-Maps) das Lesen und Aktualisieren wesentlich effizienter gestalten. Anstatt mit einer tief verschachtelten Struktur zu arbeiten, ordnen Sie Entitäten anhand ihrer IDs zu.

Beispiel: Lesen aus einem normalisierten Geschäft mit IDs

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}

); }

Dieses Muster ermöglicht einen effizienten Datenzugriff, insbesondere bei großen Datensätzen, bei denen Aktualisierungen oder Lesevorgänge schnell erfolgen müssen, ohne dass die gesamte Sammlung neu gerendert werden muss.

3. Doppelt verknüpfte Listen?: Navigation mit Kontext

Doppelt verknüpfte Listen sind nützlich, wenn Sie Kontext sowohl zum vorherigen als auch zum nächsten Element benötigen – denken Sie an die Navigation durch eine Fotogalerie, in der jedes Bild seine benachbarten Bilder als Referenz anzeigt. Anstatt einen Index zu verwenden, speichern wir den aktuellen Knoten direkt im Komponentenstatus.

Beispiel: Doppelt verknüpfte Liste zur Navigation zwischen Elementen mit Kontext

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} )}
); }

In dieser React-Komponente:

  • Der aktuelle Knoten wird im Status gespeichert und die Benutzeroberfläche wird basierend darauf aktualisiert, ob es einen vorherigen oder nächsten Knoten gibt.
  • Mit den Schaltflächen können Benutzer in der Liste vorwärts und rückwärts navigieren und sie deaktivieren, wenn keine weiteren Knoten zum Verschieben vorhanden sind.
  • Diese Struktur simuliert Echtzeitnavigation mit Kontext aus den umgebenden Elementen, die häufig in UI-Komponenten wie Karussells, Mediengalerien oder Wiedergabelisten verwendet werden.

4. Stapel?: Rückgängig-/Wiederholen-Funktionalität mit unveränderlichem Verhalten

Mit

Stacks können Sie Rückgängig-/Wiederholen-Vorgänge mithilfe der LIFO-Logik (Last In, First Out) effizient verwalten. Durch die Verwendung unveränderlicher Operationen (Concat, Slice) können wir sicherstellen, dass der Zustand unverändert bleibt.

Beispiel: Rückgängig machen/Wiederherstellen mit unveränderlichem Push und Pop

const [undoStack, setUndoStack] = useState([]); const [redoStack, setRedoStack] = useState([]); const [formState, setFormState] = useState({ name: '', email: '' }); const updateForm = (newState) => { setUndoStack(prev => prev.concat([formState])); // Unveränderlicher Push setRedoStack([]); // Redo-Stack löschen setFormState(newState); }; const undo = () => { if (undoStack.length > 0) { const lastState = undoStack.at(-1); setUndoStack(prev => prev.slice(0, -1)); // Unveränderlicher Pop setRedoStack(prev => prev.concat([formState])); // Aktuellen Status in „Wiederherstellen“ verschieben setFormState(lastState); } }; const redo = () => { if (redoStack.length > 0) { const lastRedo = redoStack.at(-1); setRedoStack(prev => prev.slice(0, -1)); // Unveränderlicher Pop setUndoStack(prev => prev.concat([formState])); // Aktuellen Status zum Rückgängigmachen verschieben setFormState(lastRedo); } };
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. Warteschlangen?: Sequentielle API-Aufrufe verwalten

Warteschlangen funktionieren nach dem Prinzip „First In, First Out“ (FIFO) und eignen sich hervorragend, um sicherzustellen, dass Aufgaben wie API-Aufrufe oder Benachrichtigungen in der richtigen Reihenfolge verarbeitet werden.

Beispiel

:

API-Aufrufe in die Warteschlange stellen const [apiQueue, setApiQueue] = useState([]); const enqueueApiCall = (apiCall) => { setApiQueue(prevQueue => prevQueue.concat([apiCall])); // Unveränderlicher Push }; const ProcessQueue = () => { if (apiQueue.length > 0) { const [nextCall, ...restQueue] = apiQueue; nextCall().finally(() => setApiQueue(restQueue)); // Unveränderlicher Pop } };

6. Bäume?: Rekursive Komponenten rendern
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);
  }
};
Bäume werden in React häufig verwendet, wenn es um verschachtelte Komponenten wie

Kommentarthreads

,

Ordnerstrukturen oder Menüs geht. Beispiel

:

Rekursives Rendern eines Kommentarbaums const commentTree = { ID: 1, Text: „Erster Kommentar“, Kinder: [ { id: 2, text: „Antwort auf ersten Kommentar“, untergeordnete Elemente: [] }, { id: 3, text: „Eine weitere Antwort“, untergeordnete Elemente: [{ id: 4, text: „Verschachtelte Antwort“ }] } ] }; Funktion Comment({ comment }) { zurückkehren (

{comment.text}

{comment.children?.map(child => (
))}
); }
Ein weiterer beliebter Beitrag, der für Sie relevant sein könnte:
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 => (
))}
); }


Beispiel 1

:

Routing zwischen mehreren Ansichten Sie können Routen zwischen Seiten als Diagramm darstellen und so flexible Navigationspfade in einem SPA gewährleisten.
constroutesGraph = { home: ['about', 'contact'], über: ['home', 'team'], Kontakt: ['Zuhause'], }; Funktion navigation(currentRoute, targetRoute) { if (routesGraph[currentRoute].includes(targetRoute)) { console.log(`Navigation von ${currentRoute} zu ${targetRoute}`); } anders { console.log(`Ungültige Route von ${currentRoute} zu ${targetRoute}`); } }

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}`);
  }
}
:

Benutzerbeziehungsmodellierung Diagramme eignen sich perfekt zur Modellierung sozialer Verbindungen oder jeder Art von Beziehung, bei der mehrere Einheiten miteinander verbunden sind.
constuserGraph = { Benutzer1: ['Benutzer2', 'Benutzer3'], Benutzer2: ['Benutzer1', 'Benutzer4'], Benutzer3: ['Benutzer1'], Benutzer4: ['Benutzer2'] }; Funktion findConnections(userId) { returnuserGraph[userId] || []; } console.log(findConnections('user1')); // Ausgaben: ['user2', 'user3']

Hinweis: Wir verwenden Diagramme, um Prüferabhängigkeiten in Middleware anzuzeigen.
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);
  }
};
TL;DR – Diese Schulstunden zahlen sich aus

Diese DSA-Klassen fühlten sich früher vielleicht abstrakt an, aber Datenstrukturen treiben die Welt um Sie herum in React an.

Objekte, Stapel, Warteschlangen, verknüpfte Listen, Bäume und Diagramme sind mehr als nur Theorie – sie sind das Rückgrat der sauberen, effizienten und skalierbaren Apps, die Sie jeden Tag erstellen.

Wenn Sie also das nächste Mal den Status in einer Warteschlange verwalten oder sich mit komplexer UI-Logik befassen, denken Sie daran: Sie haben seit der Schule dafür trainiert. ?

Lassen Sie mich wissen, welche Datenstrukturen Sie am häufigsten verwendet haben!

Freigabeerklärung Dieser Artikel ist abgedruckt unter: https://dev.to/jayantbh/frontend-dev-data-structures-algorithms-how-dsa-can-power-your-react-app-491a?1 Wenn es einen Verstoß gibt, bitte Kontaktieren Sie Study_golang@163 .comdelete
Neuestes Tutorial Mehr>

Haftungsausschluss: Alle bereitgestellten Ressourcen stammen teilweise aus dem Internet. Wenn eine Verletzung Ihres Urheberrechts oder anderer Rechte und Interessen vorliegt, erläutern Sie bitte die detaillierten Gründe und legen Sie einen Nachweis des Urheberrechts oder Ihrer Rechte und Interessen vor und senden Sie ihn dann an die E-Mail-Adresse: [email protected] Wir werden die Angelegenheit so schnell wie möglich für Sie erledigen.

Copyright© 2022 湘ICP备2022001581号-3