


[Ü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: useState
,useEffect
,抑或是别的hooks,子组件它们本身也是个函数。因此我们自然可以利用相同的思路来处理函数组件的复杂性问题:通过建立一个新函数,来把即符合公共模式又复杂的代码封装起来。
比较常见的处理复杂组件的方式是把它分解成多个子组件。但是这么做可能会让人觉得不自然或是很难准确的去描述这些子组件。这时候我们就可以借助梳理组件的钩子函数的逻辑来发现新的抽象点。
每当我们在组件内看到由useState
、useEffect
或是其他内置钩子函数组成的长长的列表时,我们就应该去考虑是否可以将它们提取到一个自定义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> ); }
我们要把钩子逻辑提取到一个自定义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; }
必须用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> ); }
可以发现,我们现在在组件内部无法调用任何的setter
函数,即无法改变状态。在这个组件我们已经不需要包含修改状态的逻辑,这些逻辑都包含在了useRepos
Durch die Erstellung einer neuen Funktion können wir komplexen Code kapseln, der einem gemeinsamen Muster entspricht
Immer wenn wir eine lange Liste von
🎜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 mituseState
,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.use
beginnt (hier nennen wir sieuseRepos
). ): 🎜rrreee🎜muss mituse
beginnen, da daslinter
-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🎜 undas const
. Der Typhinweis hier dient nur dazu, sicherzustellen, dass die Typinferenz korrekt ist: ein Array mit 3 Elementen, die Typen sindRepo[], 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 hieras const
hinzu. Der Unterschied in der ts-Typinferenz spiegelt sich hauptsächlich in der Anzahl der numerischen Elemente wider. Ohne das Hinzufügen vonas const
ist der abgeleitete Typ(string | boolean | Repo[] | null)[]
und die hinzugefügte Typinferenz istreadonly [Repo[ ], boolean, string |. null]
. 🎜🎜🎜Wenden Sie den benutzerdefinierten HookuseRepos
auf unsere Komponente an und der Code lautet: 🎜rrreee🎜Sie können feststellen, dass wir jetzt keinensetter
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-FunktionuseRepos
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
钩子函数。如果钩子更新了,可能使用某种形式的缓存,或者通过轮询或更复杂的方法进行持续更新,那么引用了这个钩子的所有组件都将受益。
当然,提取自定义钩子除了可以方便复用外,还有别的好处。在我们的例子中,所有的useState
和useEffect
都是为了实现同一个功能——就是获取库用户列表,我们把这个看作一个原子功能,那么在一个组件中,包含很多个这样的原子功能也是很常见的。如果我们把这些原子功能的代码都分别提取到不同的自定义钩子函数中,就更容易发现哪些状态在我们修改代码逻辑时要保持同步更新,不容易出现遗漏的情况。除此之外,这么做的好处还有:
- 越短小的函数越容易看懂
- 为原子功能命名的能力(如useRepo)
- 更自然的提供文档说明(每个自定义钩子函数的功能更加内聚单一,这种函数也很容易去写注释)
最后
我们已经了解到React的钩子函数并没有多么神秘,也和其他函数一样很容易就可以创建。我们可以创建自己的领域特定的钩子,进而在整个应用程序中重用。也可以在各种博客或“钩子库”中找到很多预先编写好的通用钩子。这些钩子可以想useState
和useEffect
一样很方便的在我们的项目中应用。Dan Abramov的useInterval
钩子就是一个例子,例如你有一个类似于useRepos
的钩子,但是你需要可以轮询更新?那你就可以尝试在你的钩子中使用useInterval
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
unduseEffect
. DeruseInterval
-Hook von Dan Abramov ist ein Beispiel. Sie haben beispielsweise einen Hook, deruseRepos
ä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!

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen



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 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

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 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

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

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.

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 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
