Blitz.js एक रिएक्ट फ्रेमवर्क है जिसे मूल रूप से Next.js से फोर्क किया गया था। आज हम एक Blitz.js To-Do एप्लिकेशन बनाएंगे जो कार्यों को Upstash में संग्रहीत करता है। आगे की हलचल के बिना, चलिए शुरू करते हैं!
सेटअप
आरंभ करने के लिए आपको अपने कंप्यूटर पर Blitz.js इंस्टॉल करना होगा।
एनपीएम:
npm install -g blitz --legacy-peer-deps
सूत:
yarn global add blitz
एक नया Blitz.js ऐप बनाने के लिए, blitz new
. का उपयोग करें और निर्देशिका में सीडी।
blitz new blitzjs-todo && cd blitzjs-todo
बढ़िया, अब हमारी वेबसाइट को स्टाइल करने के लिए TailwindCSS इंस्टॉल करें।
blitz install tailwind
अंत में, Upstash JS SDK को स्थापित करें ताकि Upstash API को कॉल करना आसान हो सके।
एनपीएम:
npm i @upstash/redis
सूत:
yarn i @upstash/redis
इस बिंदु पर, आपको blitz dev
चलाना चाहिए यह सुनिश्चित करने के लिए कि सब कुछ ठीक से काम कर रहा है। खाता बनाने और साइन इन करने का भी प्रयास करें। यदि आपने अब तक सब कुछ सही ढंग से किया है तो यह इस तरह दिखना चाहिए।
इसके अलावा, आपकी फ़ाइल संरचना इस तरह दिखनी चाहिए:
इन्हें कॉपी करें UPSTASH_REDIS_REST_URL
और UPSTASH_REDIS_REST_TOKEN
Upstash कंसोल से .env
. नामक फ़ाइल में अभी के लिए। यह इस तरह दिखना चाहिए:
# This env file should be checked into source control
# This is the place for default values for all environments
# Values in `.env.local` and `.env.production` will override these values
UPSTASH_REDIS_REST_URL=YOUR_URL_HERE
UPSTASH_REDIS_REST_TOKEN=YOUR_TOKEN_HERE
हमने अपना Blitz.js एप्लिकेशन अभी पूरी तरह से सेट कर लिया है! आइए अपनी टू-डू सूची को लागू करना शुरू करें।
कार्यान्वयन
Blitz.js में निर्मित उपयोगकर्ता प्रमाणीकरण के साथ आता है! आइए प्रत्येक उपयोगकर्ता के लिए निजी टू-डू सूचियां बनाने के लिए इसका लाभ उठाएं।
सबसे पहले, Upstash JS SDK को /lib/redis.ts
में इनिशियलाइज़ करें
import { Redis } from "@upstash/redis";
const redis = Redis.fromEnv();
export default redis;
हमें 3 . बनाना होगा हमारी टू-डू सूचियों तक पहुंचने के लिए विभिन्न एपीआई रूट।
app/api
पर नेविगेट करें और getall.ts
. नाम की एक फाइल बनाएं . एक बार ऐसा करने के बाद, निम्न कोड को इसमें पेस्ट करें:
import { BlitzApiRequest, BlitzApiResponse, getSession } from "blitz";
import redis from "../../lib/redis";
export const handler = async (req: BlitzApiRequest, res: BlitzApiResponse) => {
const session = await getSession(req, res);
if (!session.userId) {
res.status(401).json({ error: `Do not tamper with this route!` });
} else {
await redis
.lrange(String(session.userId), 0, 100)
.then((data) => res.status(200).json({ data: data, success: true }))
.catch((error) => res.status(500).json({ error: error }));
}
};
export default handler;
आइए देखें कि यह एपीआई रूट कैसे काम करता है, चरण दर चरण। सबसे पहले, हम मार्ग के लिए अनुरोध करते हैं। मार्ग पर ही, हम पुष्टि करते हैं कि उपयोगकर्ता लॉग इन है। यदि कोई उपयोगकर्ता नहीं है, तो हम "अधिकृत नहीं" प्रतिक्रिया लौटाते हैं। अगर वहाँ है एक उपयोगकर्ता, फिर हम सूची में वर्तमान में मौजूद सभी टू-डॉस को खोजने के लिए अपना अपस्टैश रेडिस डेटाबेस प्राप्त करते हैं। इससे लगभग सौ टू-डॉस प्राप्त होंगे।
<ब्लॉकक्वॉट>प्रश्न:रुको, हम पहली बार में टू-डॉस कैसे जोड़ने वाले हैं?ए:अच्छा सवाल! चलिए इसे आगे करते हैं!
एक बार फिर, निम्न कोड को add.ts
. नामक एक नई फ़ाइल में पेस्ट करें app/api
में ।
import { BlitzApiRequest, BlitzApiResponse, getSession } from "blitz";
import redis from "../../lib/redis";
const handler = async (req: BlitzApiRequest, res: BlitzApiResponse) => {
const session = await getSession(req, res);
if (req.method !== "POST" || !req.body.data || !session.userId) {
res.status(401).json({ error: `Do not tamper with this route!` });
} else {
let todo = encodeURI(req.body.data);
await redis
.lpush(String(session.userId), todo)
.then(() => res.status(200).json({ success: true }))
.catch(() => res.status(500).json({ error: "Error adding data." }));
}
};
export default handler;
यह एपीआई मार्ग पिछले एक के समान है, लेकिन ध्यान दें कि हमने पांचवीं पंक्ति में और अधिक चेक जोड़े हैं। ऐसा इसलिए है क्योंकि यह अनुरोध GET
नहीं है अनुरोध, बल्कि, यह एक POST
है अनुरोध। ध्यान दें कि हम तीन चीजों की जांच कैसे करते हैं। सबसे पहले, हम सुनिश्चित करते हैं कि अनुरोध वास्तव में एक POST
है अनुरोध। इसके बाद, हम सुनिश्चित करते हैं कि req.body.data
. में JSON या टेक्स्ट है . अंत में, हम सुनिश्चित करते हैं कि उपयोगकर्ता लॉग इन है। यदि ये सभी छोटे चेक पास हो जाते हैं, तो हम अपने टू-डू को अपस्टैश पर अपनी रेडिस सूची में धकेल सकते हैं। यदि लाते समय किसी प्रकार की त्रुटि होती है, तो हम .catch
. का उपयोग करके 500 वापस कर सकते हैं ।
आखिरी रास्ता जो हमें जोड़ने की जरूरत है, वह है हमारे टू-डॉस को हटाना। एक बार जब आप कुछ खत्म कर लेते हैं, तो आपको निश्चित रूप से इसे पार करना होगा! आइए अपना आखिरी एपीआई रूट app/api/remove.ts
. में जोड़ें . निम्न कोड को फ़ाइल में कॉपी करें:
import { BlitzApiRequest, BlitzApiResponse, getSession } from "blitz";
import redis from "../../lib/redis";
const handler = async (req: BlitzApiRequest, res: BlitzApiResponse) => {
const session = await getSession(req, res);
if (req.method !== "POST" || !req.body.data || !session.userId) {
res.status(401).json({ error: `Do not tamper with this route!` });
} else {
let todo = encodeURI(req.body.data);
await redis
.lrem(String(session.userId), 1, todo)
.then(() => res.status(200).json({ success: true }))
.catch(() => res.status(500).json({ error: "Error removing data." }));
}
};
export default handler;
कुछ ऐसा ही नोटिस करें? ऐसा इसलिए है क्योंकि यह मार्ग लगभग add
. के समान है एपीआई मार्ग। यहाँ मुख्य अंतर यह है कि हम LREM
. का उपयोग कर रहे हैं , नहीं LPUSH
, Redis से किसी आइटम को हटाने के लिए।
बिल्डिंग द फ़्रंटएंड
शुरू करने के लिए, आइए app/pages/index.js
. से सब कुछ हटा दें और हमारी टू-डू सूची को चरण दर चरण लिखें।
फ़ाइल के शीर्ष पर, इन आयातों को इसमें चिपकाएँ।
import { Link, BlitzPage, useMutation, Routes, getAntiCSRFToken } from "blitz";
import { useRef, useEffect, useState, Suspense } from "react";
import Layout from "app/core/layouts/Layout";
import { useCurrentUser } from "app/core/hooks/useCurrentUser";
import logout from "app/auth/mutations/logout";
हम अपनी टू-डू सूची की मुख्य कार्यक्षमता बनाने के लिए रिएक्ट हुक का उपयोग करेंगे। आइए सूची की कुछ मुख्य विशेषताओं को लागू करें।
const Main = () => {
const todoRef = useRef<HTMLInputElement>(null)
const [todos, setTodos] = useState([])
const currentUser = useCurrentUser()
const [logoutMutation] = useMutation(logout)
const handleAddTodo = async (e) => {
e.preventDefault()
const antiCSRFToken = await getAntiCSRFToken()
const response = await fetch("/api/add", {
method: "POST",
headers: {
"Content-Type": "application/json",
"anti-csrf": antiCSRFToken,
},
body: JSON.stringify({ data: todoRef.current?.value }),
})
const data = await response.json()
if (data.success) {
todoRef.current!.value = ""
fetchTodos()
}
}
const handleRemoveTodo = async (id) => {
const antiCSRFToken = await getAntiCSRFToken()
const response = await fetch("/api/remove", {
method: "POST",
headers: {
"Content-Type": "application/json",
"anti-csrf": antiCSRFToken,
},
body: JSON.stringify({ data: id }),
})
const data = await response.json()
if (data.success) {
fetchTodos()
}
}
const fetchTodos = async () => {
const antiCSRFToken = await getAntiCSRFToken()
const response = await fetch("/api/getall", {
method: "GET",
headers: {
"anti-csrf": antiCSRFToken,
},
})
const res = await response.json()
setTodos(res.data)
}
useEffect(() => {
fetchTodos()
}, [])
if (currentUser) {
return (
<>
<button
className="mt-4 px-2 py-1 border-2 border-black hover:bg-gray-400 mb-3"
onClick={async () => {
await logoutMutation()
}}
>
Logout
</button>
<div>
User id: <code>{currentUser.id}</code>
<br />
User email: <code>{currentUser.email}</code>
</div>
<form className="mt-2" onSubmit={handleAddTodo}>
<p>add a todo:</p>
<input
ref={todoRef}
className="w-full border-black border-2 focus:outline-none text-center"
/>
</form>
<div className="flex flex-col gap-2 mt-4 bg-gray-300 rounded-md">
{(todos as string[]).map((todo: string, index: number) => (
<div className="flex items-center p-3 rounded-md bg-gray-300" key={index}>
<button
onClick={() => handleRemoveTodo(todo)}
className="flex items-center mr-4 justify-center w-5 h-5 rounded-[0.25rem] border border-solid border-gray-500 shadow-sm hover:bg-gray-700"
></button>
<span>{todo}</span>
</div>
))}
</div>
</>
)
} else {
return (
<div className="flex flex-col gap-4 text-center">
<Link href={Routes.SignupPage()}>
<a className="mt-4 px-2 py-1 border-2 border-black hover:bg-gray-400">
<strong>Sign Up</strong>
</a>
</Link>
<Link href={Routes.LoginPage()}>
<a className="mt-4 px-2 py-1 border-2 border-black hover:bg-gray-400">
<strong>Login</strong>
</a>
</Link>
</div>
)
}
}
<Main/>
घटक हमारे आवेदन का मूल है। इसके कोड को करीब से देखने पर पता चलता है कि हम इसका उपयोग कैसे करते हैं। हमारे घटक के शीर्ष पर, हम अपने आवेदन के लिए राज्य को प्रारंभ करते हैं। हम एक ref
. भी घोषित करते हैं हमारे "नए टू-डू" इनपुट में बाद में उपयोग के लिए। आप antiCSRFToken
. के उपयोग को भी नोटिस कर सकते हैं ! Blitz.js को किसी भी प्रकार के दुर्भावनापूर्ण अभिनेता को आपकी साइट को नुकसान पहुंचाने से रोकने के लिए कोई भी API रूट प्राप्त करते समय इन टोकन के उपयोग की आवश्यकता होती है। मेरे विचार से यह अच्छा है!
हम वेबसाइट पर अपने डेटा को संभालने के लिए तीन मुख्य कार्यों का उपयोग करते हैं। ये तीन हैं:
handleAddTodo
handleRemoveTodo
fetchTodos
हम fetchTodos
. कहते हैं जैसे ही पृष्ठ लोड होता है, सभी टू-डॉस को लोड करने के लिए जिसे उपयोगकर्ता को अभी भी पूरा करने की आवश्यकता होती है। जब कोई उपयोगकर्ता टू-डू को हटाता है या जोड़ता है, तो हम fetchTodos
. कहते हैं वेबसाइट पर उस बदलाव को फिर से दिखाने के लिए!
यदि कोई उपयोगकर्ता लॉग इन नहीं है, तो उपयोगकर्ता को इस पृष्ठ को देखने से पहले वेबसाइट पर लॉगिन करने के लिए प्रेरित किया जाएगा।
यदि आपके पास वेबसाइट पर पहले से कोई सत्र नहीं है तो आप साइन अप या लॉग इन कर सकते हैं। याद रखें, आप अपने टू-डॉस को एक खाते के बिना स्टोर नहीं कर सकते हैं, और सभी एपीआई रूटों के लिए आपको AntiCSRFToken
के साथ प्रमाणित होना आवश्यक है। !
लेकिन रुकिए, एक और महत्वपूर्ण कदम! हमें पेज को एक्सपोर्ट करना है!
const Home: BlitzPage = () => {
return (
<div className="flex flex-col min-h-screen items-center justify-center">
<main>
<div className="my-4">
<Suspense fallback="Loading...">
<Main />
</Suspense>
</div>
</main>
</div>
);
};
Home.suppressFirstRenderFlicker = true;
Home.getLayout = (page) => <Layout title="Home">{page}</Layout>;
export default Home;
जैसा कि आप ऊपर देख सकते हैं, Blitz.js एक दृष्टिकोण का उपयोग करता है जो नेक्स्ट से थोड़ा अलग है, लेकिन अभी के लिए इसके मूल में दृष्टिकोण समान है। हम Suspense
. का उपयोग करते हैं जिसे हमने पहले एक उपयोगकर्ता को दिखाने के लिए आयात किया था कि ऐप लोड हो रहा है, और फिर हम अपना </Main>
दिखाते हैं घटक लोड होने के बाद!
अपने परिवर्तनों को प्रभाव में देखने के लिए, इसे अपने कंसोल में एक बार और चलाएं, और ब्राउज़र में अपने ऐप पर नेविगेट करें।
blitz dev
यदि आपने निर्देशों का पालन किया है, तो एक बार लॉग इन करने के बाद आपका आवेदन कुछ इसी तरह दिखना चाहिए और कुछ टू-डॉस जोड़ें:
आप एक टू-डू को उसके आगे वाले बॉक्स पर क्लिक करके हटा सकते हैं, जो कि removeTodo
है फ़ंक्शन 😉 के लिए है।
बधाई हो!
मुझे आशा है कि आपने इस ब्लॉग पोस्ट को पढ़कर कुछ नया सीखा है, और यदि आपने नहीं किया है, तो याद रखें कि आपके कौशल को बढ़ाने में कोई हर्ज नहीं है! Blitz.js, Next.js से ध्यान हटा रहा है, इसलिए भविष्य में यह पूरी तरह से अलग ढांचा हो सकता है, लेकिन यहां उनकी वेबसाइट पर बने रहें!
परियोजना स्रोत :गिटहब लिंक
कार्य प्रदर्शन: डेमो लिंक
प्रतिक्रिया है? ट्विटर पर @upstash का अनुसरण करना सुनिश्चित करें, और डिस्कॉर्ड सर्वर से जुड़ें!