Ushbu maqola nima haqida?
Ushbu maqolada siz React.js va Socket.io-dan foydalanib jamoaviy ishlar ro’yxatini qanday yaratishni o’rganasiz. Foydalanuvchilar Socket.io orqali ishlarni yaratish, o‘qish va o‘chirish, shuningdek, har bir ishga izoh qo‘shish imkoniyatiga ega bo‘ladi. Vazifalar yaratilganda yoki oʻchirilganda, ilova bildirishnoma jo’natadigan qilishni ham oʻrganasiz.
Novu – birinchi ochiq manbali bildirishnoma (notification) tizimi.
Novu – bu birinchi ochiq manbali bildirishnoma (elektron pochta, SMS va boshqalar) tizimidir.
Socket.io nima?
Socket.io – bu mashhur JavaScript kutubxonasi boʻlib, u bizga web-brauzerlar va Node.js serveri oʻrtasida bir vaqtda ikki yoʻnalishli aloqani yaratish imkonini beradi. Bu katta hajmdagi maʼlumotlarni minimal kechikish bilan qayta ishlashga moʻljallangan yuqori unumdorli va mustahkam kutubxona. U WebSocket protokoliga amal qiladi va HTTP uzoq so’rovidan qaytish yoki avtomatik qayta ulanish kabi yaxshi funksionallikni ta’minlaydi, bu esa o’z o’rnida bizga real vaqtda samarali ilovalar yaratish imkonini beradi.
React va Socket.io orasida birikmani qanday yaratish mumkin?
Bu erda siz ilovani yaratish uchun loyiha muhitini o’rnatasiz. Shuningdek, siz ilovaga Socket.io ni qanday qo‘shishni va Socket.io orqali real vaqt rejimida muloqot qilish uchun React va Node.js serverini ulashni o‘rganasiz.
Loyiha papkasini yarating. Uning ichida client – ya’ni mijoz, hamda server – ya’ni server nomli papkalarni oching.
mkdir todo-list
cd todo-list
mkdir client server
Terminal orqali client papkasiga o’ting va yangi React.js loyihasini yarating.
cd client
npx create-react-app ./
Socket.io kengaytmasini va Reaсt Routerni o‘rnating. React Router – bu JavaScript kutubxonasi bo‘lib, u bizga React ilovasidagi sahifalar orasida harakat qilish imkonini beradi.
npm install socket.io-client react-router-dom
React ilovasidan logotip va test fayllari kabi ortiqcha fayllarni o’chirib tashlang va App.js faylini quyida ko‘rsatilganidek Hello World ko‘rsatishi uchun yangilang.
function App() {
return (
<div>
<p>Hello World!</p>
</div>
);
}
export default App;
Server papkasiga o’ting va package.json faylini yarating.
cd server & npm init –y
Express.js, CORS, Nodemon va Socket.io Server API-sini o’rnating.
Express.js – Node.js ni tez, oddiy kutubxonasi bo’lib, unda web-ilovalarini yaratish uchun bir nechta xususiyatlarni taqdim etadi. CORS – bu turli domenlar o’rtasidagi aloqani ta’minlaydigan Node.js to’plami.
Nodemon – Node.js vositasi boʻlib, fayllarni oʻzgarishini aniqlagandan soʻng serverni avtomatik ravishda qayta ishga tushiradi, Socket.io esa serverda real vaqtda ulanishni oʻrnatish imkonini beradi.
npm install express cors nodemon socket.io
Serverga kirish nuqtasini, index.js faylini yarating.
touch index.js
Express.js bilan oddiy Node.js serverini sozlang. Quyidagi kod parchasi brauzerda http://localhost:4000/api ga tashrif buyurilganida JSON obyektini qaytaradi.
//index.js
const express = require("express");
const app = express();
const PORT = 4000;
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.get("/api", (req, res) => {
res.json({
message: "Hello world",
});
});
app.listen(PORT, () => {
console.log(`Server listening on ${PORT}`);
});
Mijoz va server domenlari o’rtasidagi aloqani yoqish uchun HTTP va CORS kutubxonasini import qiling.
const express = require("express");
const app = express();
const PORT = 4000;
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
// Yangi importlar
const http = require("http").Server(app);
const cors = require("cors");
app.use(cors());
app.get("/api", (req, res) => {
res.json({
message: "Hello world",
});
});
http.listen(PORT, () => {
console.log(`Server listening on ${PORT}`);
});
Keyin real vaqtda ulanishni yaratish uchun loyihaga Socket.io ni qo’shing. app.get() blokidan oldin quyidagi kodni nusxalang.
// Yangi importlar
.....
const socketIO = require('socket.io')(http, {
cors: {
origin: "http://localhost:3000"
}
});
// Buni app.get() blokidan oldin qo’ying
socketIO.on('connection', (socket) => {
console.log(`⚡: ${socket.id} user just connected!`);
socket.on('disconnect', () => {
socket.disconnect()
console.log('🔥: A user disconnected');
});
});
JSXYuqorida keltirilgan kod blokidagi socket.io(“connection”) funksiyasi React dasturi bilan birikmani o’rnatadi, keyin har bir kirgan kishi uchun noyob ID yaratadi va har safar foydalanuvchi web-sahifaga kirganda, IDni konsolga yozadi.
Web-sahifani yangilaganingizda yoki yopganingizda, foydalanuvchi chiqib ketganligini bildiradigan hodisasini ishga tushiradi.
Package.json faylidagi skriptlar ro’yxatiga start buyrug’ini qo’shish orqali Nodemonni sozlang. Quyidagi kod parchasi Nodemon yordamida serverni ishga tushiradi.
// server/package.json ichida
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "nodemon index.js"
},
JSONEndi siz quyidagi buyruq yordamida serverni Nodemon bilan ishga tushirishingiz mumkin.
npm start
BATFoydalanuvchi interfeysini yaratish.
Bu yerda biz ishlar jadvali ilovasi uchun foydalanuvchi interfeysini yaratamiz. Foydalanuvchilar tizimga kirishlari, ishlarni qo‘shishlari va o‘chirishlari hamda har bir holatga izoh qo‘shishlari mumkin bo‘ladi.
Client/src papkasiga o’ting va Home.js hamda Main.js fayllarini o’z ichiga olgan komponentlar papkasini yarating.
cd client
mkdir components
cd components
touch Home.js Main.js
BATReact Router yordamida yangi yaratilgan komponentlarni turli yo’nalishlarda ko’rsatish uchun App.js faylini yangilang.
import React from "react";
import socketIO from "socket.io-client";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import Main from "./components/Main";
import Home from "./components/Home";
const socket = socketIO.connect("http://localhost:4000");
const App = () => {
return (
<BrowserRouter>
<Routes>
<Route path='/' element={<Home />} />
<Route path='/app' element={<Main socket={socket} />} />
</Routes>
</BrowserRouter>
);
};
export default App;
JSXsrc/index.css fayliga o’ting va quyidagi koddan nusxa oling. Unda ushbu loyihani shakllantirish uchun zarur bo’lgan barcha CSS kodlari mavjud.
@import url("https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@300;400;500;600;700&display=swap");
* {
box-sizing: border-box;
margin: 0;
padding: 0;
font-family: "Space Grotesk", sans-serif;
}
.navbar {
width: 100%;
height: 10vh;
background-color: #256d85;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 20px;
color: #dff6ff;
}
.form {
width: 100%;
min-height: 20vh;
display: flex;
align-items: center;
justify-content: center;
padding: 0 30px;
}
.input {
padding: 10px 15px;
width: 80%;
margin-right: 15px;
}
.form__cta,
.home__form > button {
width: 200px;
cursor: pointer;
padding: 10px;
height: 45px;
font-size: 16px;
background-color: #256d85;
color: #dff6ff;
border: none;
outline: none;
border-radius: 3px;
}
.todo__container {
width: 100%;
display: flex;
align-items: center;
flex-direction: column;
min-height: 300px;
}
.todo__item {
display: flex;
align-items: center;
width: 70%;
padding: 20px;
background-color: #ddd;
margin: 10px 0;
justify-content: space-between;
color: #06283d;
}
.deleteBtn {
padding: 5px 10px;
background-color: rgb(202, 22, 22);
border: none;
outline: none;
color: #fff;
cursor: pointer;
}
.deleteBtn:hover {
color: rgb(202, 22, 22);
background-color: #fff;
}
.commentsBtn {
padding: 5px 10px;
margin-right: 10px;
outline: none;
cursor: pointer;
border: none;
background-color: #fff;
}
.commentsBtn:hover {
background-color: #ddd;
border: 1px solid #000;
}
.modal {
min-height: 100vh;
width: 100%;
position: fixed;
top: 0;
background-color: #fff;
display: flex;
align-items: center;
justify-content: center;
}
.modal__container {
width: 70%;
background-color: #fff;
min-height: 80vh;
padding: 30px;
border-radius: 3px;
border: 1px solid #333;
}
.modal__container > h3 {
margin-bottom: 30px;
}
.comment__form {
display: flex;
margin-bottom: 30px;
align-items: center;
}
.comment__form > input {
padding: 10px;
border: 1px solid #256d85;
width: 70%;
margin-right: 20px;
}
.comment {
margin-bottom: 5px;
}
.comment__form > button {
padding: 15px 20px;
cursor: pointer;
background-color: #256d85;
color: #fff;
outline: none;
border: none;
height: 45px;
}
.home {
width: 100%;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.home__form {
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
}
.home__form > * {
margin-bottom: 10px;
}
.home > h2 {
margin-bottom: 15px;
}
CSSBosh sahifa.
Bu erda dastur foydalanuvchi nomini qabul qiladi va foydalanuvchini aniqlash uchun uni mahalliy xotirada saqlaydi. Quyidagi kodni Home komponentiga nusxalang.
import React, { useState } from "react";
import { useNavigate } from "react-router-dom";
const Home = () => {
const [username, setUsername] = useState("");
const navigate = useNavigate();
const handleSubmit = (e) => {
e.preventDefault();
localStorage.setItem("_username", username);
// Ilovaga o'tish
navigate("/app");
};
return (
<div className='home'>
<h2>Sign in to your todo-list</h2>
<form onSubmit={handleSubmit} className='home__form'>
<label htmlFor='username'>Your Username</label>
<input
value={username}
required
onChange={(e) => setUsername(e.target.value)}
className='input'
/>
<button>SIGN IN</button>
</form>
</div>
);
};
export default Home;
JSXAsosiy component.
Bu yerda biz dasturning markaziy qismi uchun foydalanuvchi interfeysini yaratamiz.
Quyidagi kod parchasini Main.js fayliga ko’chiring.
import React, { useState } from "react";
import Nav from "./Nav";
function Main({ socket }) {
const [todo, setTodo] = useState("");
// Ish identifikatori sifatida tasodifiy qator hosil qiladi
const generateID = () => Math.random().toString(36).substring(2, 10);
const handleAddTodo = (e) => {
e.preventDefault();
// Har bir ish shunday tuzilishga ega - id, ish va sharhlar.
console.log({
id: generateID(),
todo,
comments: [],
});
setTodo("");
};
return (
<div>
<Nav />
<form className='form' onSubmit={handleAddTodo}>
<input
value={todo}
onChange={(e) => setTodo(e.target.value)}
className='input'
required
/>
<button className='form__cta'>ADD TODO</button>
</form>
<div className='todo__container'>
<div className='todo__item'>
<p>Contributing to open-source</p>
<div>
<button className='commentsBtn'>View Comments</button>
<button className='deleteBtn'>DELETE</button>
</div>
</div>
<div className='todo__item'>
<p>Coffee chat with the team</p>
<div>
<button className='commentsBtn'>View Comments</button>
<button className='deleteBtn'>DELETE</button>
</div>
</div>
<div className='todo__item'>
<p>Work on my side projects</p>
<div>
<button className='commentsBtn'>View Comments</button>
<button className='deleteBtn'>DELETE</button>
</div>
</div>
</div>
</div>
);
}
export default Main;
JSXYuqoridagi kod parchasi foydalanuvchilarga ishlarni yaratish, sharhlarni ko’rish va mavjud ishlarni o’chirish imkonini beruvchi foydalanuvchi interfeysi.
Nav komponenti ilovaning navigatsiya panelidir – keyinchalik ushbu qo‘llanmada biz ushbu komponentda Novu yordamida bildirishnomalarni yuboramiz.
Nav komponentini yarating va unga quyidagi kodni ko’chiring:
// /src/components/Nav.js ichida
import React from "react";
const Nav = () => {
return (
<nav className='navbar'>
<h2>Todo List</h2>
</nav>
);
};
export default Nav;
JSXTabriklaymiz! Siz ilova uchun foydalanuvchi interfeysini yaratdingiz. Keyingi bo’limlarda siz Socket.io yordamida real vaqtda ma’lumotlarni va Novu yordamida bildirishnomalarni qanday yuborishni o’rganasiz.
Yangi ishni qanday yaratadi.
Ushbu bo’limda men sizga yangi vazifalarni yaratish va ularni Socket.io yordamida React ilovasida ko’rsatishni ko’rsataman.
Yangi topshiriqni serverga Socket.io orqali yuborish uchun Main.js dagi handleAddTodo funksiyasini yangilang.
const handleAddTodo = (e) => {
e.preventDefault();
// Voqeani addTodo Socket.io orqali yuboradi
// id, ish va bir qator sharhlarni o'z ichiga oladi
socket.emit("addTodo", {
id: generateID(),
todo,
comments: [],
});
setTodo("");
};
JSXServerda voqea tinglovchisini yarating.
socketIO.on("connection", (socket) => {
console.log(`⚡: ${socket.id} user just connected!`);
socket.on("addTodo", (todo) => {
// Ish - React ilovasidan ob'ektni o'z ichiga oladi
console.log(todo);
});
socket.on("disconnect", () => {
socket.disconnect();
console.log("🔥: A user disconnected");
});
});
JSXIchki serverda barcha ishlarni o’z ichiga olgan massiv yarating va ro’yxatga yangi ishni qo’shing.
// Barcha rejalashtirilgan vazifalarni o'z ichiga olgan massiv
let todoList = [];
socketIO.on("connection", (socket) => {
console.log(`⚡: ${socket.id} user just connected!`);
socket.on("addTodo", (todo) => {
// Vazifalar ro'yxatiga todo ob'ektini qo'shadi.
todoList.unshift(todo);
// Barcha ishlarni React ilovasiga yuboradi
socket.emit("todos", todoList);
});
socket.on("disconnect", () => {
socket.disconnect();
console.log("🔥: A user disconnected");
});
});
JSXUseEffect ilgaki yordamida React ilovangizda vazifalar tinglovchisini yarating. Quyidagi koddan nusxa oling:
// src/components/Main.js ichida
useEffect(() => {
socket.on("todos", (data) => console.log(data));
}, [socket]);
JSXVazifalar ro’yxatini quyidagidek ko’rsating:
import React, { useState, useEffect } from "react";
import Nav from "./Nav";
function Main({ socket }) {
const [todo, setTodo] = useState("");
const [todoList, setTodoList] = useState([]);
const generateID = () => Math.random().toString(36).substring(2, 10);
const handleAddTodo = (e) => {
e.preventDefault();
socket.emit("addTodo", {
id: generateID(),
todo,
comments: [],
});
setTodo("");
};
useEffect(() => {
socket.on("todos", (data) => setTodoList(data));
}, [socket]);
return (
<div>
<Nav />
<form className='form' onSubmit={handleAddTodo}>
<input
value={todo}
onChange={(e) => setTodo(e.target.value)}
className='input'
required
/>
<button className='form__cta'>ADD TODO</button>
</form>
<div className='todo__container'>
{todoList.map((item) => (
<div className='todo__item' key={item.id}>
<p>{item.todo}</p>
<div>
<button className='commentsBtn'>View Comments</button>
<button className='deleteBtn'>DELETE</button>
</div>
</div>
))}
</div>
</div>
);
}
export default Main;
JSXHozircha biz faqat birini qo’shganimizdagina mavjud ishlarni ko’rishimiz mumkin. Keling sahifa yuklanganda vazifalarni ko’rsata oladigan qilaylik.
Serverda vazifalar ro’yxatini qaytaradigan marshrut yarating.
app.get("/api", (req, res) => {
res.json(todoList);
});
JSXServerdan vazifalar roʻyxatini olish va yangi vazifalarni tinglash uchun useEffect ilgakini yangilang.
useEffect(() => {
function fetchTodos() {
fetch("http://localhost:4000/api")
.then((res) => res.json())
.then((data) => setTodoList(data))
.catch((err) => console.error(err));
}
fetchTodos();
socket.on("todos", (data) => setTodoList(data));
}, [socket]);
JSXTabriklaymiz, endi biz vazifalar ro’yxatiga yangi ishlarni qo’shishimiz mumkin.
Mavjud ishlarni qanday o’chirish mumkin?
Tanlangan ishning identifikatorini oladigan o’chirish tugmasi uchun onClick hodisasini qo’shing.
<button className='deleteBtn' onClick={() => deleteTodo(item.id)}>
DELETE
</button>
JSXDeleteTodo funksiyasini yarating va ish identifikatorini Socket.io orqali serverga yuboring.
const deleteTodo = (id) => socket.emit("deleteTodo", id);
JSXDeleteTodo hodisasi uchun tinglovchi yarating, bu topshiriqni identifikatori boʻyicha topshiriqlar roʻyxatidan olib tashlaydi.
// Barcha rejalashtirilgan vazifalarni o'z ichiga olgan massiv
let todoList = [];
socketIO.on("connection", (socket) => {
console.log(`⚡: ${socket.id} user just connected!`);
socket.on("addTodo", (todo) => {
todoList.unshift(todo);
socket.emit("todos", todoList);
});
// Bir qator holatlarni filtrlaydi va
// yangilangan ishni React ilovasiga yuboradi.
socket.on("deleteTodo", (id) => {
todoList = todoList.filter((todo) => todo.id !== id);
// React ilovasiga yangilangan ishni yuboradi
socket.emit("todos", todoList);
});
socket.on("disconnect", () => {
socket.disconnect();
console.log("🔥: A user disconnected");
});
});
JSXEndi har bir ishni Socket.io orqali qo’shishingiz va olib tashlashingiz mumkin. Endi har bir ish uchun sharh qo’shish va ko’rsatishni o’rganasiz.
Har bir ish uchun sharhlarni qanday ko’rsatish va qo’shish.
Ushbu bo’limda men sizga har bir vazifaga sharhlar qo’shishni ko’rsataman va siz Reactda modallarni qanday yaratishni ham o’rganasiz.
React.js da modal yaratish.
Quyida ko’rsatilganidek, har bir holat uchun sharhlarni o’z ichiga olgan Modal.js faylini yarating:
import React, { useState } from "react";
const Modal = ({ socket }) => {
const [comment, setComment] = useState("");
const addComment = (e) => {
e.preventDefault();
console.log({ comment });
setComment("");
};
return (
<div className='modal'>
<div className='modal__container'>
<h3>Comments</h3>
<form className='comment__form' onSubmit={addComment}>
<input
className='comment__input'
type='text'
value={comment}
onChange={(e) => setComment(e.target.value)}
required
/>
<button>Add Comment</button>
</form>
<div className='comments__container'>
<div className='comment'>
<p>
<strong>Nevo - </strong> Hello guys
</p>
</div>
</div>
</div>
</div>
);
};
export default Modal;
JSXUshbu komponentni modal ko’rinishi uchun biz src/index.css faylida quyida bajarilganidek, unga biroz stil berishimiz kerak, ayniqsa pozitsiya va z-index stilini.
.modal {
min-height: 100vh;
width: 100%;
position: fixed;
z-index: 10;
top: 0;
background-color: #fff;
display: flex;
align-items: center;
justify-content: center;
}
CSSEndi, keling View Comment tugmasi bosilganda, Main.js faylidagi Modal.js komponenti o’zgaradigan qilaylik.
import React, { useState, useEffect } from "react";
import Nav from "./Nav";
import Modal from "./Modal";
function Main({ socket }) {
const [todo, setTodo] = useState("");
const [todoList, setTodoList] = useState([]);
const [showModal, setShowModal] = useState(false);
const toggleModal = () => setShowModal(!showModal);
//...boshqa funksiyalar
return (
<div>
...
<div className='todo__container'>
{todoList.map((item) => (
<div className='todo__item' key={item.id}>
<p>{item.todo}</p>
<div>
{/* Bu tugma Modal komponentni o’zgartiradi ---*/}
<button className='commentsBtn' onClick={toggleModal}>
View Comments
</button>
<button className='deleteBtn' onClick={() => deleteTodo(item.id)}>
DELETE
</button>
</div>
</div>
))}
</div>
{/* Modal komponent asosiy komponentni almashtiradi */}
{showModal ? (
<Modal showModal={showModal} setShowModal={setShowModal} />
) : (
""
)}
</div>
);
}
export default Main;
JSXView tugmasini bosish orqali modalni ko‘rsatish imkoniga ega bo‘ldik endi keling, sharhlar konteyneridan tashqarisini bosganimizda modal oynasini yopadigan qilamiz.
Modal.js faylini quyida ko’rsatilganidek yangilang:
import React, { useState, useRef } from "react";
const Modal = ({ socket, showModal, setShowModal }) => {
const [comment, setComment] = useState("");
const modalRef = useRef();
//(modalRef) konteynerini ustiga bosish modalni yopadi.
const closeModal = (e) => {
if (modalRef.current === e.target) {
setShowModal(!showModal);
}
};
const addComment = (e) => {
e.preventDefault();
console.log({ comment });
setComment("");
};
return (
<div className='modal' onClick={closeModal} ref={modalRef}>
...
</div>
);
};
JSXTabriklaymiz! Siz React ilovasiga modallarni qanday qo’shishni o’rgandingiz. Keling, foydalanuvchilar sharhlar qo’shishi va ko’rsatishi mumkin bo’lsin.
Ishlar sharhi ko’rsatilishi.
Tanlangan ishni identifikatorini serverga yuborish uchun Main.js dagi toggleModal funksiyasini yangilang.
const toggleModal = (todoId) => {
socket.emit("viewComments", todoId);
setShowModal(!showModal);
};
JSXServerda ish identifikatorini qabul qiladigan, uning tafsilotlarini oladigan va ularni React ilovasiga yuboradigan tinglovchi yarating.
socket.on("viewComments", (id) => {
for (let i = 0; i < todoList.length; i++) {
if (id === todoList[i].id) {
// ko'rsatish uchun bajariladigan ishlar tafsilotlarini React ilovasiga yuboradi
socket.emit("commentsReceived", todoList[i]);
}
}
});
JSXModal.js da commentsReceived hodisasi uchun tinglovchi yarating.
useEffect(() => {
socket.on("commentsReceived", (todo) => console.log(todo));
}, [socket]);
JSXQuyidagilarni nusxalash orqali sharhlaringizni kiriting:
import React, { useEffect, useRef, useState } from "react";
const Modal = ({ showModal, setShowModal, socket }) => {
const modalRef = useRef();
const [comment, setComment] = useState("");
const [comments, setComments] = useState([]);
const closeModal = (e) => {
if (modalRef.current === e.target) {
setShowModal(!showModal);
}
};
const addComment = (e) => {
e.preventDefault();
console.log({ comment });
setComment("");
};
// Serverdan topshiriq tafsilotlarini tinglaydi
useEffect(() => {
socket.on("commentsReceived", (todo) => setComments(todo.comments));
}, [socket]);
return (
<div className='modal' onClick={closeModal} ref={modalRef}>
<div className='modal__container'>
<h3>Comments</h3>
<form className='comment__form' onSubmit={addComment}>
<input
className='comment__input'
type='text'
value={comment}
onChange={(e) => setComment(e.target.value)}
required
/>
<button>Add Comment</button>
</form>
{/*Sharhlarni ko’rsatadi --- */}
<div className='comments__container'>
{comments.length > 0 ? (
comments.map((item, index) => (
<div className='comment' key={index}>
<p>
<strong>{item.name} - </strong> {item.text}
</p>
</div>
))
) : (
<p>No comments available yet...</p>
)}
</div>
</div>
</div>
);
};
export default Modal;
JSXVazifalarga sharhlar qo’shish.
Main.js da tanlangan ish identifikatorini o’z ichiga olgan holat yarating. Holatni Modal.js komponentiga o’tkazing.
const toggleModal = (itemId) => {
socket.emit("viewComments", itemId);
// Ushbu identifikatorni Modal komponentga o'tkazing
setSelectedItemID(itemId);
setShowModal(!showModal);
};
JSXSharh maʼlumotlarini serverga yuborish uchun Modal.js dagi addComment funksiyasini yangilang.
const addComment = (e) => {
e.preventDefault();
socket.emit("updateComment", {
todoID: selectedItemID, //Main.js faylidan uzatilgan identifikator
comment,
user: localStorage.getItem("_username"),
});
setComment("");
};
JSXServerda “topshiriq sharhlariga” sharh qo’shadigan addComment hodisasi tinglovchisini yarating.
socket.on("updateComment", (data) => {
// Obyektdan elementlarni yo'q qilish
const { user, todoID, comment } = data;
for (let i = 0; i < todoList.length; i++) {
//👇🏻 Gets the todo
if (todoID === todoList[i].id) {
//👇🏻 Add the comment to the list of comments
todoList[i].comments.push({ name: user, text: comment });
//👇🏻 Sends an update to React app
socket.emit("commentsReceived", todoList[i]);
}
}
});
JSXTabriklaymiz! Endi biz har bir vazifaga sharhlar qo‘shishimiz va ularni React ilovasida ko‘rsatishimiz mumkin.
Qo’shimcha: Novu bilan bildirishnomalarni yuborish.
Agar foydalanuvchi sharh yoki yangi vazifa qoʻshganda ilovangizga bildirishnomalar qoʻshmoqchi boʻlsangiz, buni Nav.js komponentidagi Novu bilan osongina qilishingiz mumkin.
Novu sizga elektron pochta, SMS va ilova ichidagi bildirishnomalar kabi turli xil bildirishnomalarni qo’shish imkonini beradi.
React va Node.js ilovasiga Novu qanday qo’shiladi?
Ilova ichidagi bildirishnomani qo‘shish uchun serverga Novu Node.js SDK va React ilovasidagi bildirishnomalar markazini o‘rnating.
#Install on the client
npm install @novu/notification-center
#Install on the server
npm install @novu/node
Quyidagi kodni bajarish orqali Novu loyihasini yarating. Sizga shaxsiylashtirilgan boshqaruv paneliga kirish huquqi beriladi.
#Install on the client
npx novu init
Novu loyihasini yaratishdan oldin siz Github-ga kirishingiz kerak bo’ladi. Quyidagi kod parchasi npx novu init-ni ishga tushirgandan so’ng bajarishingiz kerak bo’lgan qadamlarni o’z ichiga oladi.
Now let's setup your account and send your first notification
❓ What is your application name? Devto Clone
❓ Now lets setup your environment. How would you like to proceed?
> Create a free cloud account (Recommended)
❓ Create your account with:
> Sign-in with GitHub
❓ I accept the Terms and Condidtions (https://novu.co/terms) and have read the Privacy Policy (https://novu.co/privacy)
> Yes
✔Create your account successfully.
We've created a demo web page for you to see novu notifications in action.
Visit: http://localhost:57807/demo to continue
BAThttp://localhost:57807/demo demo web-sahifasiga tashrif buyuring, sahifadan obunachi identifikatoringizni nusxalang va qo’llanmani o’tkazib yuborish tugmasini bosing. Biz undan keyinroq ushbu qo’llanmada foydalanamiz.
Hujjatdagi ilova ichidagi bildirishnomalar uchun Novu va uning kerakli elementlarini o’z ichiga olishi uchun components/Nav.jsfile faylini yangilang.
import React from "react";
import {
NovuProvider,
PopoverNotificationCenter,
NotificationBell,
} from "@novu/notification-center";
import { useNavigate } from "react-router-dom";
const Nav = () => {
const navigate = useNavigate();
const onNotificationClick = (notification) =>
navigate(notification.cta.data.url);
return (
<nav className='navbar'>
<h2>Todo List</h2>
<div>
<NovuProvider
subscriberId='<YOUR_SUBSCRIBER_ID'
applicationIdentifier='<YOUR_APP_ID>'
>
<PopoverNotificationCenter
onNotificationClick={onNotificationClick}
colorScheme='light'
>
{({ unseenCount }) => (
<NotificationBell unseenCount={unseenCount} />
)}
</PopoverNotificationCenter>
</NovuProvider>
</div>
</nav>
);
};
export default Nav;
JSXYuqoridagi kod parchasi Nav komponentiga Novu bildirishnoma qo’ng’irog’i belgisini qo’shib, bizga ilova ichidagi barcha bildirishnomalarni ko’rish imkonini beradi.
NovuProvider komponenti uchun abonent identifikatoringiz talab qilinadi – avvalroq http://localhost:57807/demo saytidan koʻchirilgan va Novu Manage platformasidagi API kalitlari boʻlimidagi Sozlamalar boʻlimida mavjud ilova identifikatoringiz.
Endi, keling siz ilovaga qo’shmoqchi bo’lgan,funksiyalarni tushundiradigan, ilovaga ish jarayoni yarataylik
“Ishlab chiqish yon panelida” bildirishnomani tanlang va bildirishnoma shablonini yarating. O’zingiz yaratgan shablonni tanlang, “Ish jarayoni muharririni” bosing va ish jarayoni quyidagi kabi ko’rinishiga ishonch hosil qiling:
Yuqoridagi rasmdan tushunsak bo’ladiki, Novu ilova ichidagi bildirishnomani yuborishdan oldin, Digest mexanizmini ishga tushiradi.
Novu Digest bizga ilova ichida bildirishnomalarni qanday yuborishni nazorat qilish imkonini beradi. U bir nechta hodisalarni to’playdi va ularni bitta xabar sifatida yuboradi. Yuqoridagi rasm har 2 daqiqada bildirishnomalarni yuboradi va agar sizda ko’p foydalanuvchilar va tez-tez yangilanishlar bo’lsa, bu samarali bo’lishi mumkin.
In-Appstep tugmasini bosing va quyidagi tarkibni kiritish uchun bildirishnoma shablonini tahrirlang.
{{userId}} added a new to-do.
JSXNovu sizga Handlebars shablonlash mexanizmi yordamida shablonlarga dinamik tarkib yoki ma’lumotlarni qo’shish imkonini beradi.
Update tugmasini bosish orqali shablonni saqlang va kod muharririga qayting.
Ilovaga Novu qo’shish.
Paketdan Novu-ni import qiling va serverda API kalitingizdan foydalanib namuna yarating.
//server/index.js
const { Novu } = require("@novu/node");
const novu = new Novu("<YOUR_API_KEY>");
JSXNovu orqali React ilovasiga bildirishnoma yuboradigan funksiya yarating.
const sendNotification = async (template_id) => {
try {
const result = await novu.trigger(template_id, {
to: {
subscriberId: <SUBSCRIBER_ID>,
},
});
console.log(result);
} catch (err) {
console.error("Error >>>>", { err });
}
};
socket.on("addTodo", (todo) => {
todoList.unshift(todo);
socket.emit("todos", todoList);
// Novu orqali bildirishnomani ishga tushiradi
sendNotification("<TEMPLATE_ID>");
});
JSXYuqoridagi kod parchasi ilovaga yangi ish qo’shilganda barcha foydalanuvchilarga bildirishnoma yuboradi.
Ishlar jadvali yaratilishini yakunlaganingiz bilan tabriklaymiz!
Xulosa.
Hozirgacha siz React va Node.js ilovalarida Socket.io-ni qanday sozlashni va Socket.io orqali server va mijoz o’rtasida muloqot qilishni o’rgandingiz.
Bu Socket.io va React yordamida qurilishi mumkin bo’lgan oddiy bir ilova. Foydalanuvchi sharh qoldirganda autentifikatsiya, real vaqtda maʼlumotlar bazasi va Novu orqali bildirishnomalarni qoʻshish orqali ilovani yaxshilash mumkin.
Eng ko’p o’qilgan maqolalar