Table of contents
Après avoir implémenté le Hook useLocalStorage
pour faciliter la gestion du stockage local, implémentons le Hook useNetworkState
pour connaître
l'état du réseau de l'utilisateur (savoir s'il est connecté à internet ou non).
Motivation
Supposons que nous soyons en train de développer une application qui nécessite d'être connecté à internet en permanence pour fonctionner convenablement. Si l'utilisateur se retrouve déconnecté, un message doit être affiché, lui informant de vérifier sa connectivité. Pour ce faire, dans une application React, voici comment nous pourrions procéder.
const App = () => {
const [isOnline, setIsOnline] = useState(window.navigator.onLine);
useEffect(() => {
const handleOnline = () => setIsOnline(true);
const handleOffline = () => setIsOnline(false);
window.addEventListener('online', handleOnline);
window.addEventListener('offline', handleOffline);
return () => {
window.removeEventListener('online', handleOnline);
window.removeEventListener('offline', handleOffline);
};
}, []);
return (
<div>
<h1>My Awesome App</h1>
<p>
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Culpa
provident tenetur molestias fugiat expedita quaerat dolores dignissimos
dicta, error amet reiciendis voluptates delectus perspiciatis dolorum
saepe, sunt, similique vitae illo.
</p>
{!isOnline && (
<div className="toast">
You are offline. Please check your connectivity and try again.
</div>
)}
</div>
);
};
Ceci fonctionne parfaitement. En revanche, notre code pourrait considérablement être simplifié, notamment le
Hook useEffect
. Notre but est donc de définir un Hook useNetworkState
afin d'abstraire cette logique dans
un Hook séparé. Cela permettra à la fois de simplifier notre composant, mais aussi (et surtout) de pouvoir
réutiliser cette logique à d'autres endroits de notre application sans dupliquer de code. Maintenant que nous
savons pourquoi nous avons besoin de ce Hook, passons à l'implémentation. 👨🏻💻
Implémentation
Comme à notre habitude, réfléchissons d'abord à l'interface de notre Hook afin de savoir comment nous allons l'utiliser. Dans notre cas, nous voudrions quelque chose d'aussi simple que ça :
const isOnline = useNetworkState()
Ni plus, ni moins. Il nous retournerait une simple valeur booléenne qui sera mise à jour automatiquement et convenablement pour se synchroniser avec l'état actuel de la connectivité de l'utilisateur.
Nous pouvons donc passer à l'implémentation, qui consistera tout simplement en l'extraction de la logique que nous avons écrite précédemment au sein d'une fonction séparée. Le Hook final n'est donc pas plus compliqué que ça :
const useNetworkState = () => {
const [isOnline, setIsOnline] = useBoolean(window.navigator.onLine);
useEffect(() => {
window.addEventListener('online', setIsOnline.on);
window.addEventListener('offline', setIsOnline.off);
return () => {
window.removeEventListener('online', setIsOnline.on);
window.removeEventListener('offline', setIsOnline.off);
};
}, []);
return isOnline;
};
Euh, c'est quoi ce Hook
useBoolean
? 🤨
Effectivement, il n'est pas fourni directement par React. Cependant, pour ceux qui suivraient cette série depuis le tout début, ce Hook devrait vous rappeler quelque chose : c'est le tout premier Hook personnalisé que nous avons implémenté ensemble !
Si vous avez découvert cette série en cours de route, pas d'inquiétude : je vous invite à lire cet article pour en apprendre plus sur ce Hook.
Si vous ne souhaitez pas utiliser le Hook
useBoolean
, vous pouvez vous contenter d'un simpleuseState
.
const useNetworkState = () => {
const [isOnline, setIsOnline] = useState(window.navigator.onLine);
useEffect(() => {
const handleOnline = () => setIsOnline(true);
const handleOffline = () => setIsOnline(false);
window.addEventListener('online', handleOnline);
window.addEventListener('offline', handleOffline);
return () => {
window.removeEventListener('online', handleOnline);
window.removeEventListener('offline', handleOffline);
};
}, []);
return isOnline;
};
Utilisation
Si nous reprenons notre composant App
de tout à l'heure, voici comment il peut être simplifié
grâce à notre tout nouveau Hook :
const App = () => {
const isOnline = useNetworkState()
return (
<div>
<h1>My Awesome App</h1>
<p>
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Culpa
provident tenetur molestias fugiat expedita quaerat dolores dignissimos
dicta, error amet reiciendis voluptates delectus perspiciatis dolorum
saepe, sunt, similique vitae illo.
</p>
{!isOnline && (
<div className="toast">
You are offline. Please check your connectivity and try again.
</div>
)}
</div>
);
};
Eh oui, je vous l'avais dit, notre code est désormais bien plus simple ! 😎
Conclusion
Nous avons réussi à abstraire toute la logique de connectivité réseau à l'extérieur de notre composant,
qui se concentre maintenant sur ce qu'il doit réellement faire. Grâce à cela, nous suivons le principe
de séparation des préoccupations, ou Separation of Concerns en anglais (SOC). Vous trouverez plus
d'informations sur ce lien.
Dans le prochain article, nous allons implémenter un Hook pour utiliser plus facilement les effets
sonores : useAudio
.
Code source disponible sur CodeSandbox.