У цій статті будемо розбиратися з темою реалізації нотифікацій у вебпроєктах, а також як правильно розробляти функціонал нотифікації у вебдодатках написаних на React. Тепер до головного, почнемо з простого.
Нотифікації — це короткі повідомлення, які з’являються у додатках для інформування користувачів про події або зміни. Вони виконують важливу функцію у взаємодії з користувачами, допомагаючи зробити інтерфейс зрозумілим і зручним.
Основна мета нотифікацій — залучати увагу користувача в потрібний момент і передавати йому цінну інформацію без зайвих зусиль.
ЧОМУ ЦЕ ВАЖЛИВО?
Річ у тому що функціонал нотифікацій досить сильно підвищує UX і допомагає користувачу краще розуміти, що він робить. Це досить важливо, особливо коли функції, котрі ви розробляєте, комплексні. Задача проєкту — бути корисним для користувача, тому ми повинні пояснювати користувачу, що він робить і як тими функціями користуватися.
ЩО ТАКЕ UX (USER EXPERIENCE)?
Це досвід, який користувач отримує під час взаємодії з продуктом, вебсайтом або додатком. Це не лише про те, як щось виглядає, а й про те, наскільки зручно, інтуїтивно й ефективно користувач може досягти своєї мети під час взаємодії з інтерфейсом.
З причин описаним вище, типовою задачею, майже на будь-якому проєкті є розробка функціоналу нотифікацій, котрі будуть супроводжувати користувача про те, що він робить і на що варто звернути увагу.
ОФЛАЙН-НОТИФІКАЦІЇ
Тут усе дуже цікаво, адже такі нотифікації будуть приходити користувачу безпосередньо в його операційну систему і далі сама система буде його інформувати. Важливо зрозуміти, що я говорю не про email-листи чи sms, а мова йде саме про push-нотифікації, до котрих ми так звикли користуючись мобільними телефонами й додатками.
І, так, можна відправляти push-нотифікації з вебдодатка відразу на телефон користувача, тільки треба розібратись, як це роботи. Це не дуже важко, але досить цікаво. Ну і звісно, мова йде не тільки про мобільні телефони, але й про комп'ютери. Тобто push-нотифікації так само можна надсилати й на інші пристрої, в будь-якому випадку працювати це буде майже однаково.
Далі трохи розкажу і покажу як налаштувати push-повідомлення на своєму проєкті. Тут нам треба буде трохи розібратись з ServiceWorker, бо вся робота проходитиме через нього, а в кінці я прикріплю статтю про ServiceWorker.
НАЛАШТУВАННЯ PUSH-ПОВІДОМЛЕНЬ
Service Worker — це спеціальний скрипт, що працює у фоновому режимі та не залежить від сторінки, на якій перебуває користувач. Оскільки це фоновий скрипт, то він може працювати та виконувати операції й тоді, коли користувач не переглядає вебсайт.
Для початку нам треба зареєструвати ServiceWorker:
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('/service-worker.js')
.then(function(registration) {
// Реєстрація успішна
console.log('ServiceWorker registration successful with scope: ', registration.scope);
}, function(err) {
// Реєстрація провалилася
console.log('ServiceWorker registration failed: ', err);
});
});
}
Далі слід попросити користувача підписатись на push-повідомлення. Так-так, це найбільш правильний підхід.
document.getElementById('subscribe').addEventListener('click', function() {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.ready.then(function(registration) {
registration.pushManager.subscribe({
userVisibleOnly: true,
// Використовуйте власний вебключ для push-повідомлень
applicationServerKey: 'YOUR_WEB_PUSH_KEY'
}).then(function(subscription) {
console.log('User is subscribed:', subscription);
}).catch(function(err) {
console.log('Failed to subscribe the user: ', err);
});
});
}
});
Після цього нам потрібно додати обробник для push-повідомлення.
self.addEventListener('push', function(event) {
const options = {
body: 'Це push-повідомлення!',
icon: 'images/icon.png',
badge: 'images/badge.png'
};
event.waitUntil(
self.registration.showNotification('Push Notification', options)
);
});
НОТАТКИ
- Ви маєте згенерувати власний вебключ для push-повідомлень, який буде використовуватися в applicationServerKey у scripts/push.js.
- Для використання push-повідомлень вам також потрібно буде налаштувати backend-сервер, який відправлятиме push-повідомлення до підписаних користувачів.
- Повний приклад демонстраційного проєкту доступний за посиланням.
РОЗУМІННЯ НОТИФІКАЦІЙ У ВЕБДОДАТКАХ
Говорячи про звичайні online-нотифікації, котрі ми бачимо на кожному сайті, хотілося би для початку розбити їх на типи. Оскільки у вебдодатку ми маємо змогу керувати тзовнішнім виглядом, звуками, анімаціями нотифікацій, тут, звісно, контролю над процесом у нас набагато більше.
Типи нотифікацій
- Інформаційні:
- Використовуються для загальних повідомлень, які не потребують негайної дії.
- Приклад: «Ваш профіль оновлено успішно».
- Помилки:
- Повідомляють про проблеми, які потребують уваги користувача.
- Приклад: «Не вдалося зберегти дані. Спробуйте ще раз».
- Успіхи:
- Відображають успішне завершення дії.
- Приклад: «Ваше замовлення оформлено».
- Попередження:
- Використовуються для запобігання помилкам або важливих дій.
- Приклад: «Ваш акаунт майже заповнив доступне місце. Додайте новий тариф».
Де використовуються нотифікації?
Нотифікації застосовуються в багатьох частинах вебдодатків:
- Форми:
- Інформування про успіхи чи помилки при відправці даних.
- Процеси оплати:
- Підтвердження успішного платежу.
- Інтерактивні елементи:
- Повідомлення про завершення дій (наприклад, додавання до кошика).
- Оновлення даних:
- Інформація про статуси операцій, наприклад, оновлення профілю.
Що робить нотифікації ефективними?
- Чіткість і лаконічність:
- Повідомлення мають бути короткими та зрозумілими.
- Наприклад: «Файл завантажено» замість «Процес завантаження файлу завершено успішно».
- Видимість:
- Нотифікації мають бути помітними, але не заважати користувачу.
- Приклад: Використання легких тіней чи анімації для появи.
- Час показу:
- Нотифікації повинні автоматично закриватися через 3–5 секунд, якщо це не критичне повідомлення.
- Можливість закриття:
- Додай кнопку «Закрити» або хрестик для зручності.
РЕАЛІЗАЦІЯ НОТИФІКАЦІЙ У REACT
У цьому розділі ми виділимо 3 підходи, котрі будуть достатньо сильно відрізнятися між собою. Ціль цього — показати, що і коли краще використовувати. Найпростіший шлях не завжди поганий, а забивати цвяхи кувалдою, може бути не overkill.
1️⃣ Локальний стан у компоненті (useState)
У цьому підході ми використовуємо useState всередині одного компонента, щоб зберігати й відображати нотифікації. Це найпростіший спосіб, який не вимагає додаткових інструментів.
import React, { useState } from 'react';
const App = () => {
const [notification, setNotification] = useState(null);
const showNotification = (message, type) => {
setNotification({ message, type });
setTimeout(() => setNotification(null), 3000);
};
return (
<div>
<h1>Simple Notification Example</h1>
<button onClick={() => showNotification('This is an info message', 'info')}>Show Info</button>
<button onClick={() => showNotification('This is a success message', 'success')}>Show Success</button>
<button onClick={() => showNotification('This is an error message', 'error')}>Show Error</button>
{notification && (
<div className={`notification ${notification.type}`}>
{notification.message}
</div>
)}
</div>
);
};
export default App;
Чому це добре?
- Швидка реалізація: мінімум коду, зрозуміла логіка.
- Простота: не потрібно контекстів, зовнішніх бібліотек чи складних патернів.
- Локальність: нотифікації працюють лише в конкретному компоненті.
Чому це погано?
- Обмеження у масштабах: неможливо відправити нотифікацію з іншого компонента.
- Дублювання коду: якщо потрібно нотифікації у кількох місцях, доведеться дублювати логіку.
- Важко підтримувати: з ростом додатка важко керувати нотифікаціями.
Коли вибирати?
- Маленькі проєкти або MVP.
- Нотифікації потрібні лише в одному компоненті.
- Мінімальні вимоги до логіки.
Висновок: це як використання кувалди для забивання маленького цвяха. Працює чудово, тільки якщо задачі прості. Але як тільки з'являються глобальні вимоги — це вже не підходить.
2️⃣ Централізоване управління (React Context API)
Створюється глобальний контекст за допомогою React Context API, який забезпечує доступ до функцій для додавання, видалення і відображення нотифікацій у будь-якому компоненті.
NotificationContext.js
import React, { createContext, useContext, useState } from 'react';
const NotificationContext = createContext();
export const useNotification = () => useContext(NotificationContext);
export const NotificationProvider = ({ children }) => {
const [notifications, setNotifications] = useState([]);
const addNotification = (message, type = 'info') => {
const id = Date.now();
setNotifications((prev) => [...prev, { id, message, type }]);
setTimeout(() => removeNotification(id), 3000);
};
const removeNotification = (id) => {
setNotifications((prev) => prev.filter((notif) => notif.id !== id));
};
return (
<NotificationContext.Provider value={{ addNotification }}>
{children}
<div className="notification-container">
{notifications.map((notif) => (
<div key={notif.id} className={`notification ${notif.type}`}>
{notif.message}
</div>
))}
</div>
</NotificationContext.Provider>
);
};
App.jsx
import React from 'react';
import { NotificationProvider, useNotification } from './NotificationContext';
const AppContent = () => {
const { addNotification } = useNotification();
return (
<div>
<h1>Centralized Notification Example</h1>
<button onClick={() => addNotification('Info message', 'info')}>Show Info</button>
<button onClick={() => addNotification('Success message', 'success')}>Show Success</button>
<button onClick={() => addNotification('Error message', 'error')}>Show Error</button>
</div>
);
};
const App = () => (
<NotificationProvider>
<AppContent />
</NotificationProvider>
);
export default App;
Чому це добре?
- Глобальне керування: нотифікацію можна викликати з будь-якого місця в додатку.
- Єдине джерело правди: всі нотифікації зберігаються у єдиному сховищі.
- Легше підтримувати: одна точка контролю для всіх нотифікацій.
Чому це погано?
- Складність для новачків: потрібно розуміти, як працює Context API.
- Перевантаження контексту: велика кількість логіки у контексті може призводити до зайвих ререндерів.
- Обмежена гнучкість: немає готових анімацій чи складних налаштувань.
Коли вибирати?
- Середні додатки з помірними вимогами до нотифікацій.
- Коли потрібне глобальне керування, але немає потреби у складній кастомізації.
- Коли важливо мати централізований контроль над повідомленнями.
Висновок: це як універсальний молоток — він підходить для багатьох задач, але іноді бракує додаткових функцій, як у спеціалізованих інструментах.
3️⃣ Використання зовнішньої бібліотеки (React-Toastify)
Бібліотека React-Toastify надає готовий інтерфейс для роботи з нотифікаціями: різні типи сповіщень, гнучке налаштування, позиціюнування, анімації.
import React from 'react';
import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
const App = () => {
const notify = (type) => {
if (type === 'success') toast.success('This is a success message');
if (type === 'error') toast.error('This is an error message');
if (type === 'info') toast.info('This is an info message');
};
return (
<div>
<h1>React-Toastify Example</h1>
<button onClick={() => notify('success')}>Show Success</button>
<button onClick={() => notify('error')}>Show Error</button>
<button onClick={() => notify('info')}>Show Info</button>
<ToastContainer />
</div>
);
};
export default App;
Чому це добре?
- Швидка інтеграція: впроваджується за лічені хвилини.
- Гнучкість: можливість кастомізації, підтримка анімацій, різні позиції на екрані.
- Великий функціонал: тайм-аути, кнопки CTA, індивідуальні стилі.
- Оптимізація: нотифікації відображаються ефективно без зайвих ререндерів.
Чому це погано?
- Залежність: додаткова бібліотека у проєкті.
- Розмір бандла: збільшує розмір застосунку.
- Оверінжиніринг для дрібних задач: для простих застосунків це може бути надлишковим рішенням.
Коли вибирати?
- Великі або середні додатки з високими вимогами до UX.
- Коли потрібні кастомні нотифікації, гнучкість і підтримка різних сценаріїв.
- Коли важливий швидкий розвиток без «винаходження велосипеда».
Висновок: це як швейцарський ніж — він підходить для будь-якої задачі, має все необхідне і навіть трохи більше.
ВИСНОВОК
Нотифікації — це не просто вікна, що спливають чи маленькі повідомлення, а місток між додатком і користувачем. Вони допомагають інформувати, направляти й залучати людину у взаємодію з продуктом.
Онлайн-нотифікації чудово працюють, коли користувач активно використовує додаток: вони швидко передають інформацію, забезпечують миттєвий зворотний зв'язок і поліпшують загальний досвід взаємодії.
Push-нотифікації, зі свого боку, дозволяють підтримувати зв'язок навіть тоді, коли додаток не відкритий. Вони ідеальні для важливих сповіщень, акцій чи нагадувань, забезпечуючи присутність бренду «поза екраном».
Кожен із підходів — локальний стан, централізоване управління через Context API або використання сторонніх бібліотек, як-от React-Toastify — має свої плюси і мінуси. Важливо вибрати те, що найкраще відповідає масштабам і цілям вашого проєкту.
Головне правило: не ускладнюйте там, де можна зробити просто, і завжди думайте про користувача. Нотифікації повинні допомагати, а не дратувати.