Comments 10
Спасибо за пост, забавно что взять тот же Apollo (правда это GraphQL), так большинство этих паттернов становится не нужными (кроме Observer) в проекте
"К недостаткам можно случай, если при размонтировании компонента не удалить события, на которые вы были подписаны, React может продолжать отслеживать изменения, что приведет к утечке памяти и потере производительности."
useEffect(() => {
// это
window.addEventListener("online", () => setOnline(true));
window.addEventListener("offline", () => setOnline(false));
return () => {
// и это - разные обработчики
// зарегистрированные обработчики удалены не будут
// получаем утечку памяти при каждом использовании наблюдателя
window.removeEventListener("online", () => setOnline(true));
window.removeEventListener("offline", () => setOnline(false));
};
}, []);
Правильно я понимаю, что нужно вместо стрелки передать конкретную функцию везде, и тогда заработает корректно?
useEffect(() => {
const onlineHandler = () => setOnline(true);
const offlineHandler = () => setOnline(true);
window.addEventListener("online", onlineHandler);
window.addEventListener("offline", offlineHandler);
return () => {
// и это - разные обработчики
// зарегистрированные обработчики удалены не будут
// получаем утечку памяти при каждом использовании наблюдателя
window.removeEventListener("online", onlineHandler);
window.removeEventListener("offline", offlineHandler);
};
}, []);
Только я вспомнил картинку про буханку и трамвай?
По поводу паттерна Observer правильнее было бы иметь вот такой код:
import { useEffect, useState } from "react";
export const InternetAvailabilityObserver = () => {
const [isOnline, setOnline] = useState<any>(navigator.onLine);
const onlineSetter = () => setOnline(true);
const offlineSetter = () => setOnline(false);
useEffect(() => {
window.addEventListener("online", onlineSetter);
window.addEventListener("offline", () => offlineSetter);
return () => {
// when component gets unmounted, remove the event listeners to prevent memory leaks
window.removeEventListener("online", onlineSetter);
window.removeEventListener("offline", offlineSetter);
};
}, []);
return (
<><h1>Internet Availability Observer</h1><p>
{isOnline ? (
<><span>
You are <b>online</b></span></>
) : (
<><span>
You are <b>offline</b></span></>
)}
</p>
</>
);
};
Функции в JS являются объектами и никогда не имеют ссылку на ту же область в памяти где существуют. Поэтому в приведенном в статье примере memory leak будет случаться каждый раз при размонтировке компонента
Использование шаблонов проектирования группы GoF в React