Benutzerdefinierte React-Hooks sind ein unverzichtbares Tool, mit dem Sie Ihren React-Anwendungen besondere, einzigartige Funktionen hinzufügen können.
Wenn Sie Ihrer Anwendung eine bestimmte Funktion hinzufügen möchten, können Sie in vielen Fällen einfach eine Bibliothek eines Drittanbieters installieren, die speziell für die Lösung Ihres Problems entwickelt wurde. Aber wenn eine solche Bibliothek oder ein solcher Hook nicht existiert, was tun Sie dann?
Als React-Entwickler ist es wichtig, den Prozess der Erstellung benutzerdefinierter Hooks zu erlernen, um Probleme zu lösen oder fehlende Funktionen in Ihren eigenen React-Projekten hinzuzufügen.
In dieser Schritt-für-Schritt-Anleitung zeige ich Ihnen, wie Sie Ihre eigenen benutzerdefinierten React-Hooks erstellen, indem ich drei Hooks aufschlüssele, die ich für meine eigenen Anwendungen erstellt habe, und welche Probleme sie lösen sollen.
Ein Benutzer bewegt sich einfach mit der Maus über das Snippet, klickt auf die Schaltfläche „Zwischenablage“ und der Code wird zur Zwischenablage seines Computers hinzugefügt, damit er den Code einfügen und verwenden kann, wo immer er möchte.
copy-gif.gif
Anstatt jedoch eine Bibliothek eines Drittanbieters zu verwenden, wollte ich diese Funktionalität mit meinem eigenen benutzerdefinierten React-Hook nachbilden. Wie bei jedem benutzerdefinierten React-Hook, den ich erstelle, lege ich ihm einen dedizierten Ordner zu, der normalerweise utils oder lib heißt, speziell für Funktionen, die ich in meiner App wiederverwenden kann.
Wir werden diesen Hook in eine Datei namens useCopyToClipboard.js einfügen und ich werde eine Funktion mit demselben Namen erstellen.
Es gibt verschiedene Möglichkeiten, Text in die Zwischenablage des Benutzers zu kopieren. Ich verwende dafür lieber eine Bibliothek, die den Prozess zuverlässiger macht, genannt „In die Zwischenablage kopieren“.
Es exportiert eine Funktion, die wir Kopie nennen werden.
// utils/useCopyToClipboard.js
import React von „react“;
Kopie aus „In die Zwischenablage kopieren“ importieren;
Standardfunktion useCopyToClipboard() exportieren {}
Als Nächstes erstellen wir eine Funktion, die zum Kopieren des gewünschten Texts in die Zwischenablage des Benutzers verwendet wird. Wir nennen diese Funktion handleCopy.
So erstellen Sie die handleCopy-Funktion
Innerhalb der Funktion müssen wir zunächst sicherstellen, dass sie nur Daten vom Typ Zeichenfolge oder Zahl akzeptiert. Wir werden eine if-else-Anweisung einrichten, die sicherstellt, dass der Typ entweder eine Zeichenfolge oder eine Zahl ist. Andernfalls protokollieren wir einen Fehler in der Konsole, der dem Benutzer mitteilt, dass Sie keine anderen Typen kopieren können.
React aus „react“ importieren;
Kopie aus „In die Zwischenablage kopieren“ importieren;
Standardfunktion exportieren useCopyToClipboard() {
const [isCopied, setCopied] = React.useState(false);
Funktion handleCopy(text) {
if (typeof text === "string" || typeof text == "number") {
// kopieren
} sonst {
// nicht kopieren
console.error(
Der Typ von ${typeof text} kann nicht in die Zwischenablage kopiert werden, es muss eine Zeichenfolge oder Zahl sein.
);
}
}
}
Als nächstes nehmen wir den Text und konvertieren ihn in einen String, den wir dann an die Kopierfunktion übergeben. Von dort aus geben wir die handleCopy-Funktion vom Hook an eine beliebige Stelle in unserer Anwendung zurück.
Im Allgemeinen wird die handleCopy-Funktion mit einem onClick einer Schaltfläche verbunden.
React aus „react“ importieren;
Kopie aus „In die Zwischenablage kopieren“ importieren;
Standardfunktion exportieren useCopyToClipboard() {
Funktion handleCopy(text) {
if (typeof text === "string" || typeof text == "number") {
copy(text.toString());
} sonst {
console.error(
Der Typ von ${typeof text} kann nicht in die Zwischenablage kopiert werden, es muss eine Zeichenfolge oder Zahl sein.
);
}
}
return handleCopy;
}
Darüber hinaus möchten wir einen Status, der angibt, ob der Text kopiert wurde oder nicht. Um das zu erstellen, rufen wir useState oben in unserem Hook auf und erstellen eine neue Statusvariable isCopied, wobei der Setter setCopy.
Anfänglich ist dieser Wert falsch. Wenn der Text erfolgreich kopiert wurde, setzen wir copy auf true. Andernfalls setzen wir es auf false.
Schließlich geben wir isCopied vom Hook innerhalb eines Arrays zusammen mit handleCopy zurück.
React aus „react“ importieren;
Kopie aus „In die Zwischenablage kopieren“ importieren;
Standardfunktion exportieren useCopyToClipboard(resetInterval = null) {
const [isCopied, setCopied] = React.useState(false);
Funktion handleCopy(text) {
if (typeof text === "string" || typeof text == "number") {
copy(text.toString());
setCopied(true);
} sonst {
setCopied(false);
console.error(
Der Typ von ${typeof text} kann nicht in die Zwischenablage kopiert werden, es muss eine Zeichenfolge oder Zahl sein.
);
}
}
return [isCopied, handleCopy];
}
So verwenden Sie useCopyToClipboard
Wir können useCopyToClipboard jetzt in jeder beliebigen Komponente verwenden.
In meinem Fall verwende ich es mit einer Kopierschaltflächenkomponente, die den Code für unser Code-Snippet erhalten hat.
Damit dies funktioniert, müssen wir der Schaltfläche lediglich einen On-Click hinzufügen. Und bei der Rückgabe einer Funktion namens handle copy mit dem angeforderten Code als Text. Und sobald es kopiert ist, ist es wahr. Wir können ein anderes Symbol anzeigen, das anzeigt, dass der Kopiervorgang erfolgreich war.
React aus „react“ importieren;
ClipboardIcon aus „../svg/ClipboardIcon“ importieren;
importiere SuccessIcon aus „../svg/SuccessIcon“;
importiere useCopyToClipboard aus „../utils/useCopyToClipboard“;
Funktion CopyButton({ code }) {
const [isCopied, handleCopy] = useCopyToClipboard();
zurück (
handleCopy(code)}>
{isCopied ? : }
);
}
So fügen Sie ein Reset-Intervall hinzu
Es gibt eine Verbesserung, die wir an unserem Code vornehmen können. Da wir gerade unseren Hook geschrieben haben, wird isCopied immer wahr sein, was bedeutet, dass wir immer das Erfolgssymbol sehen:
success-gif.gif
Wenn wir unseren Status nach ein paar Sekunden zurücksetzen möchten, können Sie ein Zeitintervall an useCopyToClipboard übergeben. Fügen wir diese Funktionalität hinzu.
Zurück in unserem Hook können wir einen Parameter namens „resetInterval“ erstellen, dessen Standardwert null ist, wodurch sichergestellt wird, dass der Status nicht zurückgesetzt wird, wenn kein Argument an ihn übergeben wird.
Wir werden dann useEffect hinzufügen, um zu sagen, dass wir isCopied nach diesem Intervall mit einem setTimeout wieder auf false setzen, wenn der Text kopiert wird und wir ein Reset-Intervall haben.
Außerdem müssen wir diese Zeitüberschreitung löschen, wenn die Bereitstellung unserer Komponente, in der der Hook verwendet wird, aufgehoben wird (was bedeutet, dass unser Status nicht mehr zum Aktualisieren vorhanden ist).
React aus „react“ importieren;
Kopie aus „In die Zwischenablage kopieren“ importieren;
Standardfunktion exportieren useCopyToClipboard(resetInterval = null) {
const [isCopied, setCopied] = React.useState(false);
const handleCopy = React.useCallback((text) => {
if (typeof text === "string" || typeof text == "number") {
copy(text.toString());
setCopied(true);
} sonst {
setCopied(false);
console.error(
Der Typ von ${typeof text} kann nicht in die Zwischenablage kopiert werden, es muss eine Zeichenfolge oder Zahl sein.
);
}
}, []);
React.useEffect(() => {
Auszeit lassen;
if (isCopied && resetInterval) {
timeout = setTimeout(() => setCopied(false), resetInterval);
}
return () => {
clearTimeout(timeout);
};
}, [isCopied, resetInterval]);
return [isCopied, handleCopy];
}
Schließlich besteht die letzte Verbesserung, die wir vornehmen können, darin, handleCopy in den useCallback-Hook einzuschließen, um sicherzustellen, dass es nicht bei jedem erneuten Rendern neu erstellt wird.
Endergebnis
Und damit haben wir unseren letzten Haken, der es ermöglicht, den Status nach einem bestimmten Zeitintervall zurückzusetzen. Wenn wir einen übergeben, sollten wir ein Ergebnis wie das unten sehen.
React aus „react“ importieren;
ClipboardIcon aus „../svg/ClipboardIcon“ importieren;
importiere SuccessIcon aus „../svg/SuccessIcon“;
importiere useCopyToClipboard aus „../utils/useCopyToClipboard“;
Funktion CopyButton({ code }) {
// isCopied wird nach 3 Sekunden Timeout zurückgesetzt
const [isCopied, handleCopy] = useCopyToClipboard(3000);
zurück (
handleCopy(code)}>
{isCopied ? : }
);
}
final-result.gif
In Apps, in denen Sie unendlich scrollen können, wie zum Beispiel Instagram, müssen Sie weitere Beiträge abrufen, sobald der Benutzer das Ende der Seite erreicht.
Unendliches Scrollen in Instagram
Schauen wir uns an, wie wir selbst einen usePageBottom-Hook für ähnliche Anwendungsfälle wie das Erstellen einer unendlichen Schriftrolle erstellen können.
Wir beginnen mit der Erstellung einer separaten Datei, usePageBottom.js, in unserem Utils-Ordner und fügen eine Funktion (Hook) mit demselben Namen hinzu:
// utils/usePageBottom.js
import React von „react“;
Standardfunktion usePageBottom() exportieren {}
Als nächstes müssen wir berechnen, wann unser Benutzer das Ende der Seite erreicht. Dies können wir anhand der Informationen aus dem Fenster ermitteln. Um darauf zuzugreifen, müssen wir sicherstellen, dass unsere Komponente, in der der Hook aufgerufen wird, gemountet ist. Daher verwenden wir den useEffect-Hook mit einem leeren Abhängigkeitsarray.
// utils/usePageBottom.js
import React von „react“;
Standardfunktion usePageBottom() exportieren {
React.useEffect(() => {}, []);
}
Der Benutzer hat zum Ende der Seite gescrollt, wenn der innerHeight-Wert des Fensters plus der scrollTop-Wert des Dokuments gleich der offsetHeight ist. Wenn diese beiden Werte gleich sind, ist das Ergebnis wahr und der Benutzer ist zum Ende der Seite gescrollt:
// utils/usePageBottom.js
import React von „react“;
Standardfunktion usePageBottom() exportieren {
React.useEffect(() => {
window.innerHeight + document.documentElement.scrollTop ===
document.documentElement.offsetHeight;
}, []);
}
Wir speichern das Ergebnis dieses Ausdrucks in einer Variablen, isBottom, und aktualisieren eine Statusvariable namens „bottom“, die wir letztendlich von unserem Hook zurückgeben.
// utils/usePageBottom.js
import React von „react“;
Standardfunktion usePageBottom() exportieren {
const [bottom, setBottom] = React.useState(false);
React.useEffect(() => {
const isBottom =
window.innerHeight + document.documentElement.scrollTop ===
document.documentElement.offsetHeight;
setBottom(isButton);
}, []);
zurück nach unten;
}
Unser Code in seiner jetzigen Form funktioniert jedoch nicht. Warum nicht?
Das Problem liegt darin, dass wir isBottom jedes Mal berechnen müssen, wenn der Benutzer scrollt. Daher müssen wir mit window.addEventListener auf ein Scroll-Ereignis warten. Wir können diesen Ausdruck neu bewerten, indem wir eine lokale Funktion namens handleScroll.
erstellen, die immer dann aufgerufen wird, wenn der Benutzer einen Bildlauf durchführt// utils/usePageBottom.js
import React von „react“;
Standardfunktion usePageBottom() exportieren {
const [bottom, setBottom] = React.useState(false);
React.useEffect(() => {
Funktion handleScroll() {
const isBottom =
window.innerHeight + document.documentElement.scrollTop
=== document.documentElement.offsetHeight;
setBottom(isButton);
}
window.addEventListener("scroll", handleScroll);
}, []);
zurück nach unten;
}
Da wir schließlich über einen Ereignis-Listener verfügen, der den Status aktualisiert, müssen wir das Ereignis verarbeiten, dass unser Benutzer die Seite verlässt und unsere Komponente entfernt wird. Wir müssen den von uns hinzugefügten Scroll-Ereignis-Listener entfernen, damit wir nicht versuchen, eine Statusvariable zu aktualisieren, die nicht mehr existiert.
Wir können dies tun, indem wir eine Funktion von useEffect zusammen mit window.removeEventListener zurückgeben, wobei wir einen Verweis auf dieselbe handleScroll-Funktion übergeben. Und wir sind fertig.
// utils/usePageBottom.js
import React von „react“;
Standardfunktion usePageBottom() exportieren {
const [bottom, setBottom] = React.useState(false);
React.useEffect(() => {
Funktion handleScroll() {
const isBottom =
window.innerHeight + document.documentElement.scrollTop
=== document.documentElement.offsetHeight;
setBottom(isButton);
}
window.addEventListener("scroll", handleScroll);
return () => {
window.removeEventListener("scroll", handleScroll);
};
}, []);
zurück nach unten;
}
Jetzt können wir diesen Code einfach in jeder Funktion aufrufen, bei der wir wissen möchten, ob wir das Ende der Seite erreicht haben oder nicht.
Auf meiner Gatsby-Website habe ich eine Kopfzeile, und wenn ich die Größe der Seite verkleinere, möchte ich weniger Links anzeigen.
Größe des Fensters ändern, um die Kopfzeile anzuzeigen
Dazu könnten wir eine Medienabfrage (CSS) verwenden, oder wir könnten einen benutzerdefinierten React-Hook verwenden, um uns die aktuelle Größe der Seite zu geben und die Links in unserem JSX auszublenden oder anzuzeigen.
Zuvor habe ich einen Hook aus einer Bibliothek namens „react-use“ verwendet. Anstatt eine komplette Bibliothek eines Drittanbieters mitzubringen, habe ich beschlossen, einen eigenen Hook zu erstellen, der die Abmessungen des Fensters, sowohl die Breite als auch die Höhe, bereitstellt. Ich habe diesen Hook useWindowSize.
genanntSo erstellen Sie den Haken
Zuerst erstellen wir eine neue Datei .js in unserem Ordner „Utilities“ (utils) mit demselben Namen wie der Hook „useWindowSize“. Ich importiere React (um Hooks zu verwenden), während ich den benutzerdefinierten Hook exportiere.
// utils/useWindowSize.js
React aus „react“ importieren;
Standardfunktion useWindowSize() exportieren {}
Da ich dies nun auf einer Gatsby-Site verwende, die vom Server gerendert wird, muss ich die Größe des Fensters ermitteln. Aber wir haben möglicherweise keinen Zugriff darauf, weil wir uns auf dem Server befinden.
Um zu überprüfen und sicherzustellen, dass wir uns nicht auf dem Server befinden, können wir sehen, ob der Fenstertyp nicht mit der Zeichenfolge undefiniert übereinstimmt.
In diesem Fall können wir zu einer Standardbreite und -höhe für einen Browser zurückkehren, beispielsweise 1200 und 800 innerhalb eines Objekts:
// utils/useWindowSize.js
React aus „react“ importieren;
Standardfunktion useWindowSize() exportieren {
if (typeof window !== "undefiniert") {
return { width: 1200, height: 800 };
}
}
So ermitteln Sie die Breite und Höhe des Fensters
Und vorausgesetzt, wir befinden uns auf dem Client und können das Fenster abrufen, können wir den useEffect-Hook verwenden, um einen Nebeneffekt durch Interaktion mit dem Fenster auszuführen. Wir fügen ein leeres Abhängigkeitsarray ein, um sicherzustellen, dass die Effektfunktion erst aufgerufen wird, wenn die Komponente (in der dieser Hook aufgerufen wird) gemountet ist.
Um die Fensterbreite und -höhe herauszufinden, können wir einen Ereignis-Listener hinzufügen und auf das Größenänderungsereignis warten. Und wann immer sich die Browsergröße ändert, können wir einen Zustandsabschnitt (erstellt mit useState) aktualisieren, den wir windowSize nennen, und der Setter zum Aktualisieren ist setWindowSize.
// utils/useWindowSize.js
React aus „react“ importieren;
Standardfunktion useWindowSize() exportieren {
if (typeof window !== "undefiniert") {
return { width: 1200, height: 800 };
}
const [windowSize, setWindowSize] = React.useState();
React.useEffect(() => {
window.addEventListener("resize", () => {
setWindowSize({ width: window.innerWidth, height: window.innerHeight });
});
}, []);
}
Wenn die Fenstergröße geändert wird, wird der Rückruf aufgerufen und der windowSize-Status wird mit den aktuellen Fensterabmessungen aktualisiert. Um das zu erreichen, setzen wir die Breite auf window.innerWidth und die Höhe auf window.innerHeight.
So fügen Sie SSR-Unterstützung hinzu
Allerdings wird der Code, wie wir ihn hier haben, nicht funktionieren. Dies liegt daran, dass eine wichtige Regel für Hooks darin besteht, dass sie nicht bedingt aufgerufen werden können. Daher können wir über unserem useState- oder useEffect-Hook keine Bedingung haben, bevor sie aufgerufen werden.
Um dies zu beheben, legen wir den Anfangswert von useState bedingt fest. Wir erstellen eine Variable namens isSSR, die die gleiche Prüfung durchführt, um zu sehen, ob das Fenster nicht mit der Zeichenfolge undefiniert übereinstimmt.
Und wir verwenden einen Ternär, um die Breite und Höhe festzulegen, indem wir zunächst prüfen, ob wir uns auf dem Server befinden. Wenn ja, verwenden wir den Standardwert, andernfalls verwenden wir window.innerWidth und window.innerHeight.
// utils/useWindowSize.js
React aus „react“ importieren;
Standardfunktion useWindowSize() exportieren {
// if (typeof window !== "undefiniert") {
// return { width: 1200, height: 800 };
// }
const isSSR = typeof window !== "undefiniert";
const [windowSize, setWindowSize] = React.useState({
Breite: isSSR ? 1200: window.innerWidth,
Höhe: isSSR ? 800 : window.innerHeight,
});
React.useEffect(() => {
window.addEventListener("resize", () => {
setWindowSize({ width: window.innerWidth, height: window.innerHeight });
});
}, []);
}
Dann müssen wir endlich darüber nachdenken, wann unsere Komponenten ausgehängt werden. Was müssen wir tun? Wir müssen unseren Resize-Listener entfernen.
So entfernen Sie den Größenänderungs-Ereignis-Listener
Sie können dies tun, indem Sie eine Funktion von useEffectand zurückgeben. Wir werden den Listener mit window.removeEventListener.
// utils/useWindowSize.js
React aus „react“ importieren;
Standardfunktion useWindowSize() exportieren {
// if (typeof window !== "undefiniert") {
// return { width: 1200, height: 800 };
// }
const isSSR = typeof window !== "undefiniert";
const [windowSize, setWindowSize] = React.useState({
Breite: isSSR ? 1200: window.innerWidth,
Höhe: isSSR ? 800 : window.innerHeight,
});
React.useEffect(() => {
window.addEventListener("resize", () => {
setWindowSize({ width: window.innerWidth, height: window.innerHeight });
});
return () => { window.removeEventListener("resize", () => { setWindowSize({ width: window.innerWidth, height: window.innerHeight }); }); };
}, []);
}
Aber wir brauchen einen Verweis auf dieselbe Funktion, nicht auf zwei verschiedene, wie wir es hier haben. Dazu erstellen wir eine gemeinsame Rückruffunktion für beide Listener mit dem Namen „changeWindowSize.
“.Und schließlich geben wir am Ende des Hooks unseren windowSize-Status zurück. Und das ist es.
// utils/useWindowSize.js
React aus „react“ importieren;
Standardfunktion useWindowSize() exportieren {
const isSSR = typeof window !== "undefiniert";
const [windowSize, setWindowSize] = React.useState({
Breite: isSSR ? 1200: window.innerWidth,
Höhe: isSSR ? 800 : window.innerHeight,
});
Funktion changeWindowSize() {
setWindowSize({ width: window.innerWidth, height: window.innerHeight });
}
React.useEffect(() => {
window.addEventListener("resize", changeWindowSize);
return () => { window.removeEventListener("resize", changeWindowSize); };
}, []);
return windowSize;
}
Endergebnis
Um den Hook zu verwenden, müssen wir ihn nur dort importieren, wo wir ihn brauchen, ihn aufrufen und die Breite überall dort verwenden, wo wir bestimmte Elemente ein- oder ausblenden möchten.
In meinem Fall liegt das bei der 500px-Marke. Dort möchte ich alle anderen Links ausblenden und nur die Schaltfläche „Jetzt beitreten“ anzeigen, wie Sie im Beispiel oben sehen:
// Components/StickyHeader.js
React aus „react“ importieren;
importiere useWindowSize aus „../utils/useWindowSize“;
Funktion StickyHeader() {
const { width } = useWindowSize();
zurück (
Dieser Hook funktioniert mit jeder vom Server gerenderten React-App, wie Gatsby und Next.js.
Aber als ich auf dem Handy nachsah, war alles fehl am Platz und kaputt.
App-Fehler reagieren
Ich habe das Problem auf eine Bibliothek namens „react-device-detect“ zurückgeführt, die ich verwendet habe, um zu erkennen, ob Benutzer ein mobiles Gerät hatten oder nicht. Wenn ja, würde ich den Header entfernen.
// templates/course.js
import React von „react“;
import { isMobile } from „react-device-detect“;
Funktion Course() {
zurück (
<>
{!isMobile && }
{/* weitere Komponenten... */}
>
);
}
Das Problem bestand darin, dass diese Bibliothek keine Unterstützung für serverseitiges Rendering bietet, was Gatsby standardmäßig verwendet. Deshalb musste ich meine eigene Lösung erstellen, um zu überprüfen, wann ein Benutzer ein mobiles Gerät nutzte. Und dafür habe ich beschlossen, einen benutzerdefinierten Hook mit dem Namen useDeviceDetect.
zu erstellenWie ich den Hook erstellt habe
Ich habe für diesen Hook eine separate Datei mit demselben Namen in meinem Utils-Ordner erstellt, useDeviceDetect.js. Da es sich bei Hooks lediglich um gemeinsam nutzbare JavaScript-Funktionen handelt, die React-Hooks nutzen, habe ich eine Funktion namens „useDeviceDetect“ erstellt und React importiert.
// utils/useDeviceDetect.js
import React von „react“;
Standardfunktion useDeviceDetect() exportieren {}
So erhalten Sie den Benutzeragenten aus dem Fenster
Über die userAgent-Eigenschaft (befindet sich in der navigator-Eigenschaft von window) können wir sicherstellen, dass wir Informationen über das Gerät des Benutzers erhalten können.
Und da die Interaktion mit der Fenster-API als API/externe Ressource als Nebeneffekt eingestuft würde, müssen wir Zugriff auf den Benutzeragenten innerhalb des useEffect-Hooks erhalten.
// utils/useDeviceDetect.js
import React von „react“;
Standardfunktion useDeviceDetect() exportieren {
React.useEffect(() => {
console.log(Gerät des Benutzers ist: ${window.navigator.userAgent});
// kann auch als 'navigator.userAgent'
geschrieben werden
}, []);
}
Sobald die Komponente gemountet ist, können wir mithilfe des Navigatortyps feststellen, ob wir uns auf dem Client oder Server befinden. Wenn wir uns auf dem Server befinden, haben wir keinen Zugriff auf das Fenster. „typeof navigator“ entspricht der Zeichenfolge „undefiniert“, da sie nicht vorhanden ist. Andernfalls können wir, wenn wir uns auf dem Client befinden, unsere User-Agent-Eigenschaft abrufen.
Wir können dies alles mit einem Ternär ausdrücken, um die UserAgent-Daten zu erhalten:
// utils/useDeviceDetect.js
import React von „react“;
Standardfunktion useDeviceDetect() exportieren {
React.useEffect(() => {
const userAgent =
Art des Navigators === "undefiniert" ? "" : navigator.userAgent;
}, []);
}
So überprüfen Sie, ob userAgent ein mobiles Gerät ist
userAgent ist ein Zeichenfolgenwert, der auf einen der folgenden Gerätenamen gesetzt wird, wenn sie ein mobiles Gerät verwenden:
Android, BlackBerry, iPhone, iPad, iPod, Opera Mini, IEMobile oder WPDesktop.
Alles, was wir tun müssen, ist, die Zeichenfolge, die wir erhalten, zu nehmen und die Methode .match() mit einem regulären Ausdruck zu verwenden, um zu sehen, ob es sich um eine dieser Zeichenfolgen handelt. Wir speichern es in einer lokalen Variablen namens mobile.
Wir speichern das Ergebnis im Zustand mit dem useState-Hook, dem wir den Anfangswert false zuweisen. Dafür erstellen wir eine entsprechende Statusvariable isMobile und der Setter wird setMobile sein.
// utils/useDeviceDetect.js
import React von „react“;
Standardfunktion useDeviceDetect() exportieren {
const [isMobile, setMobile] = React.useState(false);
React.useEffect(() => {
const userAgent =
typeof window.navigator === "undefiniert" ? "" : navigator.userAgent;
const mobile = Boolean(
userAgent.match(
/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile|WPDesktop/i
)
);
setMobile(mobile);
}, []);
}
Sobald wir also den mobilen Wert erhalten haben, legen wir ihn in den Status fest. Dann geben wir schließlich ein Objekt vom Hook zurück, damit wir in Zukunft weitere Werte hinzufügen können, wenn wir diesem Hook mehr Funktionalität hinzufügen möchten.
Innerhalb des Objekts fügen wir isMobile als Eigenschaft und Wert hinzu:
// utils/useDeviceDetect.js
import React von „react“;
Standardfunktion useDeviceDetect() exportieren {
const [isMobile, setMobile] = React.useState(false);
React.useEffect(() => {
const userAgent =
typeof window.navigator === "undefiniert" ? "" : navigator.userAgent;
const mobile = Boolean(
userAgent.match(
/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile|WPDesktop/i
)
);
setMobile(mobile);
}, []);
return { isMobile };
}
Endergebnis
Zurück auf der Landingpage können wir den Hook ausführen und diese Eigenschaft einfach vom destrukturierten Objekt abrufen und dort verwenden, wo wir sie benötigen.
// templates/course.js
import React von „react“;
importiere useDeviceDetect aus „../utils/useDeviceDetect“;
Funktion Course() {
const { isMobile } = useDeviceDetect();
zurück (
<>
{!isMobile && }
{/* weitere Komponenten... */}
>
);
}
Fazit
Wie ich versucht habe, anhand jedes dieser Beispiele zu veranschaulichen, können benutzerdefinierte React-Hooks uns die Werkzeuge an die Hand geben, um unsere eigenen Probleme zu beheben, wenn Bibliotheken von Drittanbietern nicht ausreichen.
Ich hoffe, dass dieser Leitfaden Ihnen eine bessere Vorstellung davon gegeben hat, wann und wie Sie Ihre eigenen React-Hooks erstellen. Fühlen Sie sich frei, jeden dieser Hooks und den oben genannten Code in Ihren eigenen Projekten und als Inspiration für Ihre eigenen benutzerdefinierten React-Hooks zu verwenden.
Das obige ist der detaillierte Inhalt vonSo erstellen Sie Ihre eigenen React Hooks: Eine Schritt-für-Schritt-Anleitung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!