Inhaltsverzeichnis
Umgang mit Komplexität
最后
Endlich
Heim Web-Frontend js-Tutorial [Übersetzung] Refactoring von React-Komponenten mithilfe benutzerdefinierter Hooks

[Übersetzung] Refactoring von React-Komponenten mithilfe benutzerdefinierter Hooks

Jan 17, 2023 pm 08:13 PM
javascript 前端 react.js

[Übersetzung] Refactoring von React-Komponenten mithilfe benutzerdefinierter Hooks

Ich höre oft Leute über React-Funktionskomponenten sprechen und erwähnen, dass Funktionskomponenten zwangsläufig größer werden und eine komplexere Logik haben. Schließlich haben wir die Komponente in „einer Funktion“ geschrieben, sodass Sie akzeptieren müssen, dass die Komponente erweitert wird und die Funktion weiterhin erweitert wird. Es wird auch in React-Komponenten erwähnt:

Da Funktionskomponenten immer mehr Dinge tun können, werden die Funktionskomponenten in Ihrer Codebasis insgesamt immer länger. [Verwandte Empfehlungen: Redis-Video-Tutorial, Programmiervideo]

Es wird auch erwähnt, dass wir:

Versuchen sollten, das vorzeitige Hinzufügen von Abstraktionen zu vermeiden

Wenn Sie CodeScene verwenden, stellen Sie möglicherweise fest, dass eine Warnung ausgegeben wird Sie, wenn Ihre Funktion zu lang oder komplex ist. Wenn wir dem folgen, was wir zuvor gesagt haben, können wir darüber nachdenken, ob wir CodeScene-bezogene Warnungen umfassender konfigurieren sollten. Natürlich ist dies möglich, aber ich denke, wir sollten dies nicht tun, und wir sollten uns nicht weigern, dem Code viele Abstraktionen hinzuzufügen. Wir können viele Vorteile daraus ziehen, aber die Kosten sind es meistens nicht hoch. Wir können die Gesundheit unseres Codes weiterhin sehr gut halten!

Umgang mit Komplexität

Wir sollten uns darüber im Klaren sein, dass die Funktionskomponente zwar in „einer Funktion“ geschrieben ist, diese Funktion jedoch wie andere Funktionen auch aus vielen anderen Funktionen bestehen kann. Wie useState, useEffect oder andere Hooks sind auch Unterkomponenten selbst Funktionen. Daher können wir natürlich dieselbe Idee verwenden, um mit der Komplexität von Funktionskomponenten umzugehen: useStateuseEffect ,抑或是别的hooks,子组件它们本身也是个函数。因此我们自然可以利用相同的思路来处理函数组件的复杂性问题:通过建立一个新函数,来把即符合公共模式又复杂的代码封装起来

比较常见的处理复杂组件的方式是把它分解成多个子组件。但是这么做可能会让人觉得不自然或是很难准确的去描述这些子组件。这时候我们就可以借助梳理组件的钩子函数的逻辑来发现新的抽象点。

每当我们在组件内看到由useStateuseEffect 或是其他内置钩子函数组成的长长的列表时,我们就应该去考虑是否可以将它们提取到一个自定义hook中去。自定义hook函数是一种可以在其内部使用其他钩子函数的函数,并且创建一个自定义钩子函数也很简单。

如下所示的组件相当于一个看板,用一个列表展示一个用户仓库的数据(想像成和github类似的)。这个组件并不算是个复杂组件,但是它是展示如何应用自定义hook的一个不错的例子。

function Dashboard() {
  const [repos, setRepos] = useState<Repo[]>([]);
  const [isLoadingRepos, setIsLoadingRepos] = useState(true);
  const [repoError, setRepoError] = useState<string | null>(null);

  useEffect(() => {
    fetchRepos()
      .then((p) => setRepos(p))
      .catch((err) => setRepoError(err))
      .finally(() => setIsLoadingRepos(false));
  }, []);

  return (
    <div className="flex gap-2 mb-8">
      {isLoadingRepos && <Spinner />}
      {repoError && <span>{repoError}</span>}
      {repos.map((r) => (
        <RepoCard key={i.name} item={r} />
      ))}
    </div>
  );
}
Nach dem Login kopieren

我们要把钩子逻辑提取到一个自定义hook中,我们只需要把这些代码复制到一个以use 开头的函数中(在这里我们将其命名为useRepos):

/**
 * 请求所有仓库用户列表的hook函数
 */
export function useRepos() {
  const [repos, setRepos] = useState<Repo[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    fetchRepos()
      .then((p) => setRepos(p))
      .catch((err) => setError(err))
      .finally(() => setIsLoading(false));
  }, []);

  return [repos, isLoading, error] as const;
}
Nach dem Login kopieren

必须用use 开头的原因是linter 插件可以检测到你当前创建的是个钩子函数而不是普通函数,这样插件就可以检查你的钩子函数是否符合正确的自定义钩子的相关规则

相比提炼之前,提炼后出现的新东西只有返回语句as const 。这里的类型提示只是为了确保类型推断是正确的:一个包含3个元素的数组,类型分别是Repo[], boolean, string | null 。当然,你可以从钩子函数返回任何你希望返回的东西。

译者注:这里添加as const 在ts类型推断的区别主要体现在数字元素的个数。不添加as const ,推断的类型为(string | boolean | Repo[] | null)[],添加后的类型推断为readonly [Repo[], boolean, string | null]

将自定义钩子useRepos 应用在我们的组件中,代码变成了:

function Dashboard() {
  const [repos, isLoadingRepos, repoError] = useRepos();

  return (
    <div className="flex gap-2 mb-8">
      {isLoadingRepos && <Spinner />}
      {repoError && <span>{repoError}</span>}
      {repos.map((i) => (
        <RepoCard key={i.name} item={i} />
      ))}
    </div>
  );
}
Nach dem Login kopieren

可以发现,我们现在在组件内部无法调用任何的setter 函数,即无法改变状态。在这个组件我们已经不需要包含修改状态的逻辑,这些逻辑都包含在了useReposDurch die Erstellung einer neuen Funktion können wir komplexen Code kapseln, der einem gemeinsamen Muster entspricht

.

Der üblichere Weg, mit komplexen Komponenten umzugehen, besteht darin, sie in mehrere Unterkomponenten zu zerlegen. Dies könnte sich jedoch unnatürlich anfühlen oder die genaue Beschreibung dieser Unterkomponenten erschweren. Zu diesem Zeitpunkt können wir neue abstrakte Punkte entdecken, indem wir die Logik der Hook-Funktion der Komponente klären.

Immer wenn wir eine lange Liste von useState, useEffect oder anderen integrierten Hook-Funktionen in einer Komponente sehen, sollten wir überlegen, ob wir sie in einen benutzerdefinierten Hook extrahieren können . Eine benutzerdefinierte Hook-Funktion ist eine Funktion, die andere darin enthaltene Hook-Funktionen verwenden kann, und das Erstellen einer benutzerdefinierten Hook-Funktion ist ebenfalls einfach.

🎜Die unten gezeigte Komponente entspricht einem Dashboard, das eine Liste verwendet, um die Daten eines Benutzerlagers anzuzeigen (stellen Sie sich das ähnlich wie bei Github vor). Diese Komponente ist keine komplexe Komponente, aber sie ist ein gutes Beispiel für die Anwendung benutzerdefinierter Hooks. 🎜rrreee🎜Wir werden die Hook-Logik in einen benutzerdefinierten Hook extrahieren. Wir müssen diesen Code nur in eine Funktion kopieren, die mit use beginnt (hier nennen wir sie useRepos). ): 🎜rrreee🎜muss mit use beginnen, da das linter-Plug-in erkennen kann, dass es sich bei dem, was Sie gerade erstellen, um eine Hook-Funktion und nicht um eine gewöhnliche Funktion handelt, sodass die Plug-in Sie können überprüfen, ob Ihre Hook-Funktion dem richtigen benutzerdefinierten Hook entsprichtVerwandte Regeln 🎜. 🎜🎜Im Vergleich zu vor der Verfeinerung waren die einzigen neuen Dinge, die nach der Verfeinerung auftauchten, 🎜Rückgabeanweisungen🎜 und as const. Der Typhinweis hier dient nur dazu, sicherzustellen, dass die Typinferenz korrekt ist: ein Array mit 3 Elementen, die Typen sind Repo[], boolean, string null. Natürlich können Sie mit der Hook-Funktion alles zurückgeben, was Sie möchten. 🎜🎜🎜Anmerkung des Übersetzers: Fügen Sie hier as const hinzu. Der Unterschied in der ts-Typinferenz spiegelt sich hauptsächlich in der Anzahl der numerischen Elemente wider. Ohne das Hinzufügen von as const ist der abgeleitete Typ (string | boolean | Repo[] | null)[] und die hinzugefügte Typinferenz ist readonly [Repo[ ], boolean, string |. null]. 🎜🎜🎜Wenden Sie den benutzerdefinierten Hook useRepos auf unsere Komponente an und der Code lautet: 🎜rrreee🎜Sie können feststellen, dass wir jetzt keinen setter innerhalb der Komponente aufrufen können. Funktionen können nicht geändert werden Zustand. In dieser Komponente müssen wir die Logik zum Ändern des Status nicht mehr einbinden. Diese Logik ist in der Hook-Funktion useRepos enthalten. Wenn Sie sie wirklich benötigen, können Sie sie natürlich in der Return-Anweisung der Hook-Funktion verfügbar machen. 🎜🎜Was sind die Vorteile davon? In der Dokumentation von React wird Folgendes erwähnt:🎜🎜🎜Durch das Extrahieren benutzerdefinierter Hook-Funktionen kann die Komponentenlogik wiederverwendet werden🎜

Wir können uns einfach vorstellen, dass, wenn andere Komponenten in dieser Anwendung auch die Benutzerliste im Warehouse anzeigen müssen, diese Komponente lediglich die Hook-Funktion useRepos importieren muss. Wenn der Hook aktualisiert wird, möglicherweise mithilfe einer Form von Caching oder einer kontinuierlichen Aktualisierung über Abfragen oder einen komplexeren Ansatz, profitieren alle Komponenten, die auf diesen Hook verweisen. useRepos 钩子函数。如果钩子更新了,可能使用某种形式的缓存,或者通过轮询或更复杂的方法进行持续更新,那么引用了这个钩子的所有组件都将受益。

当然,提取自定义钩子除了可以方便复用外,还有别的好处。在我们的例子中,所有的useStateuseEffect 都是为了实现同一个功能——就是获取库用户列表,我们把这个看作一个原子功能,那么在一个组件中,包含很多个这样的原子功能也是很常见的。如果我们把这些原子功能的代码都分别提取到不同的自定义钩子函数中,就更容易发现哪些状态在我们修改代码逻辑时要保持同步更新,不容易出现遗漏的情况。除此之外,这么做的好处还有:

  • 越短小的函数越容易看懂
  • 为原子功能命名的能力(如useRepo)
  • 更自然的提供文档说明(每个自定义钩子函数的功能更加内聚单一,这种函数也很容易去写注释)

最后

我们已经了解到React的钩子函数并没有多么神秘,也和其他函数一样很容易就可以创建。我们可以创建自己的领域特定的钩子,进而在整个应用程序中重用。也可以在各种博客或“钩子库”中找到很多预先编写好的通用钩子。这些钩子可以想useStateuseEffect 一样很方便的在我们的项目中应用。Dan Abramov的useInterval钩子就是一个例子,例如你有一个类似于useRepos 的钩子,但是你需要可以轮询更新?那你就可以尝试在你的钩子中使用useInterval

Natürlich erleichtert das Extrahieren benutzerdefinierter Hooks nicht nur die Wiederverwendung, sondern hat auch andere Vorteile. In unserem Beispiel werden alle useState und useEffect verwendet, um die gleiche Funktion zu erreichen – um die Bibliotheksbenutzerliste zu erhalten. Wir betrachten dies als eine atomare Funktion, die ebenfalls üblich ist dass eine Komponente viele solcher atomaren Funktionen enthält. Wenn wir die Codes dieser atomaren Funktionen in verschiedene benutzerdefinierte Hook-Funktionen extrahieren, ist es einfacher herauszufinden, welche Zustände synchron aktualisiert werden müssen, wenn wir die Codelogik ändern, wodurch die Wahrscheinlichkeit geringer ist, dass sie übersehen werden. Darüber hinaus bietet dies folgende Vorteile:
  • Kürzere Funktionen sind leichter zu verstehen
  • Die Möglichkeit, atomare Funktionen zu benennen (z. B. useRepo)
  • Dokumentation bereitstellen natürlicher (die Funktion jeder benutzerdefinierten Hook-Funktion ist zusammenhängender und einzelner, und es ist einfacher, Kommentare für diese Art von Funktion zu schreiben)

Endlich

Wir haben gelernt, dass die Hook-Funktion von React nicht so mysteriös ist und wie andere Funktionen erstellt werden kann. Wir können unsere eigenen domänenspezifischen Hooks erstellen und sie in der gesamten Anwendung wiederverwenden. Sie können auch viele vorgefertigte Allzweck-Hooks in verschiedenen Blogs oder „Hook-Bibliotheken“ finden. Diese Hooks können einfach in unseren Projekten verwendet werden, genau wie useState und useEffect. Der useInterval-Hook von Dan Abramov ist ein Beispiel. Sie haben beispielsweise einen Hook, der useRepos ähnelt, aber Sie müssen in der Lage sein, Updates abzufragen? Dann können Sie versuchen, useInterval in Ihrem Hook zu verwenden.

Englische Originaladresse: https://codescene.com/engineering-blog/refactoring-components-in-react-with-custom-hooks

[Empfohlenes Lernen: 🎜Javascript-Video-Tutorial🎜]🎜

Das obige ist der detaillierte Inhalt von[Übersetzung] Refactoring von React-Komponenten mithilfe benutzerdefinierter Hooks. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Beste grafische Einstellungen
4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. So reparieren Sie Audio, wenn Sie niemanden hören können
1 Monate vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Chat -Befehle und wie man sie benutzt
1 Monate vor By 尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

WebSocket und JavaScript: Schlüsseltechnologien zur Implementierung von Echtzeitüberwachungssystemen WebSocket und JavaScript: Schlüsseltechnologien zur Implementierung von Echtzeitüberwachungssystemen Dec 17, 2023 pm 05:30 PM

WebSocket und JavaScript: Schlüsseltechnologien zur Realisierung von Echtzeit-Überwachungssystemen Einführung: Mit der rasanten Entwicklung der Internet-Technologie wurden Echtzeit-Überwachungssysteme in verschiedenen Bereichen weit verbreitet eingesetzt. Eine der Schlüsseltechnologien zur Erzielung einer Echtzeitüberwachung ist die Kombination von WebSocket und JavaScript. In diesem Artikel wird die Anwendung von WebSocket und JavaScript in Echtzeitüberwachungssystemen vorgestellt, Codebeispiele gegeben und deren Implementierungsprinzipien ausführlich erläutert. 1. WebSocket-Technologie

PHP und Vue: eine perfekte Kombination von Front-End-Entwicklungstools PHP und Vue: eine perfekte Kombination von Front-End-Entwicklungstools Mar 16, 2024 pm 12:09 PM

PHP und Vue: eine perfekte Kombination von Front-End-Entwicklungstools In der heutigen Zeit der rasanten Entwicklung des Internets ist die Front-End-Entwicklung immer wichtiger geworden. Da Benutzer immer höhere Anforderungen an das Erlebnis von Websites und Anwendungen stellen, müssen Frontend-Entwickler effizientere und flexiblere Tools verwenden, um reaktionsfähige und interaktive Schnittstellen zu erstellen. Als zwei wichtige Technologien im Bereich der Front-End-Entwicklung können PHP und Vue.js in Kombination als perfekte Waffe bezeichnet werden. In diesem Artikel geht es um die Kombination von PHP und Vue sowie um detaillierte Codebeispiele, die den Lesern helfen sollen, diese beiden besser zu verstehen und anzuwenden

Häufig gestellte Fragen von Front-End-Interviewern Häufig gestellte Fragen von Front-End-Interviewern Mar 19, 2024 pm 02:24 PM

In Front-End-Entwicklungsinterviews decken häufige Fragen ein breites Themenspektrum ab, darunter HTML/CSS-Grundlagen, JavaScript-Grundlagen, Frameworks und Bibliotheken, Projekterfahrung, Algorithmen und Datenstrukturen, Leistungsoptimierung, domänenübergreifende Anfragen, Front-End-Engineering, Designmuster sowie neue Technologien und Trends. Interviewerfragen sollen die technischen Fähigkeiten, die Projekterfahrung und das Verständnis des Kandidaten für Branchentrends beurteilen. Daher sollten Kandidaten in diesen Bereichen umfassend vorbereitet sein, um ihre Fähigkeiten und Fachkenntnisse unter Beweis zu stellen.

JavaScript und WebSocket: Aufbau eines effizienten Echtzeit-Wettervorhersagesystems JavaScript und WebSocket: Aufbau eines effizienten Echtzeit-Wettervorhersagesystems Dec 17, 2023 pm 05:13 PM

JavaScript und WebSocket: Aufbau eines effizienten Echtzeit-Wettervorhersagesystems Einführung: Heutzutage ist die Genauigkeit von Wettervorhersagen für das tägliche Leben und die Entscheidungsfindung von großer Bedeutung. Mit der Weiterentwicklung der Technologie können wir genauere und zuverlässigere Wettervorhersagen liefern, indem wir Wetterdaten in Echtzeit erhalten. In diesem Artikel erfahren Sie, wie Sie mit JavaScript und WebSocket-Technologie ein effizientes Echtzeit-Wettervorhersagesystem aufbauen. In diesem Artikel wird der Implementierungsprozess anhand spezifischer Codebeispiele demonstriert. Wir

Einfaches JavaScript-Tutorial: So erhalten Sie den HTTP-Statuscode Einfaches JavaScript-Tutorial: So erhalten Sie den HTTP-Statuscode Jan 05, 2024 pm 06:08 PM

JavaScript-Tutorial: So erhalten Sie HTTP-Statuscode. Es sind spezifische Codebeispiele erforderlich. Vorwort: Bei der Webentwicklung ist häufig die Dateninteraktion mit dem Server erforderlich. Bei der Kommunikation mit dem Server müssen wir häufig den zurückgegebenen HTTP-Statuscode abrufen, um festzustellen, ob der Vorgang erfolgreich ist, und die entsprechende Verarbeitung basierend auf verschiedenen Statuscodes durchführen. In diesem Artikel erfahren Sie, wie Sie mit JavaScript HTTP-Statuscodes abrufen und einige praktische Codebeispiele bereitstellen. Verwenden von XMLHttpRequest

Ist Django Front-End oder Back-End? Hör zu! Ist Django Front-End oder Back-End? Hör zu! Jan 19, 2024 am 08:37 AM

Django ist ein in Python geschriebenes Webanwendungs-Framework, das Wert auf schnelle Entwicklung und saubere Methoden legt. Obwohl Django ein Web-Framework ist, müssen Sie zur Beantwortung der Frage, ob Django ein Front-End oder ein Back-End ist, ein tiefes Verständnis der Konzepte von Front-End und Back-End haben. Das Front-End bezieht sich auf die Schnittstelle, mit der Benutzer direkt interagieren, und das Back-End bezieht sich auf serverseitige Programme. Sie interagieren mit Daten über das HTTP-Protokoll. Wenn das Front-End und das Back-End getrennt sind, können die Front-End- und Back-End-Programme unabhängig voneinander entwickelt werden, um Geschäftslogik bzw. interaktive Effekte sowie den Datenaustausch zu implementieren.

Erkundung der Front-End-Technologie der Go-Sprache: eine neue Vision für die Front-End-Entwicklung Erkundung der Front-End-Technologie der Go-Sprache: eine neue Vision für die Front-End-Entwicklung Mar 28, 2024 pm 01:06 PM

Als schnelle und effiziente Programmiersprache erfreut sich Go im Bereich der Backend-Entwicklung großer Beliebtheit. Allerdings assoziieren nur wenige Menschen die Go-Sprache mit der Front-End-Entwicklung. Tatsächlich kann die Verwendung der Go-Sprache für die Front-End-Entwicklung nicht nur die Effizienz verbessern, sondern Entwicklern auch neue Horizonte eröffnen. In diesem Artikel wird die Möglichkeit der Verwendung der Go-Sprache für die Front-End-Entwicklung untersucht und spezifische Codebeispiele bereitgestellt, um den Lesern ein besseres Verständnis dieses Bereichs zu erleichtern. In der traditionellen Frontend-Entwicklung werden häufig JavaScript, HTML und CSS zum Erstellen von Benutzeroberflächen verwendet

Django: Ein magisches Framework, das sowohl Front-End- als auch Back-End-Entwicklung bewältigen kann! Django: Ein magisches Framework, das sowohl Front-End- als auch Back-End-Entwicklung bewältigen kann! Jan 19, 2024 am 08:52 AM

Django: Ein magisches Framework, das sowohl Front-End- als auch Back-End-Entwicklung bewältigen kann! Django ist ein effizientes und skalierbares Webanwendungs-Framework. Es unterstützt mehrere Webentwicklungsmodelle, einschließlich MVC und MTV, und kann problemlos hochwertige Webanwendungen entwickeln. Django unterstützt nicht nur die Back-End-Entwicklung, sondern kann auch schnell Front-End-Schnittstellen erstellen und durch die Vorlagensprache eine flexible Ansichtsanzeige erreichen. Django kombiniert Front-End-Entwicklung und Back-End-Entwicklung zu einer nahtlosen Integration, sodass sich Entwickler nicht auf das Lernen spezialisieren müssen

See all articles