۵۰ درصد تخفیف ویژه برای همه دوره‌ها تا سه‌شنبه

در برنامه‌های React، مدیریت پاسخ‌های API می‌تواند به مسئله‌ای چالش‌برانگیز تبدیل شود. گاهی داده‌هایی دریافت می‌کنیم که فیلدهای ضروری را ندارند، ساختارشان غیرمنتظره است یا با قالب مورد انتظار مطابقت ندارند. وقتی توسعه‌دهنده با داده‌های ناسازگار روبه‌رو می‌شود، احتمال بروز خطا افزایش می‌یابد و مدیریت داده‌ها برای او دشوارتر می‌شود. در این شرایط، استفاده از Zod در React به عنوان راهکاری مؤثر مطرح می‌شود. این کتابخانه سبک و قدرتمند، امکان اعتبارسنجی دقیق پاسخ‌های API را فراهم می‌کند و از بروز خطاهای ناشی از داده‌های نامعتبر جلوگیری می‌نماید.

در پایان این آموزش، یاد خواهیم گرفت که چگونه:

Zod چیست و چرا باید در فراخوانی‌های API React از آن استفاده کرد؟

Zod یک کتابخانه قدرتمند مبتنی بر تایپ اسکریپت است که فرآیند اعتبارسنجی داده‌ها را ساده می‌سازد. این ابزار به ما این امکان را می‌دهد تا قوانین روشنی (اسکیماها) برای قالب داده‌های مورد انتظار خود تعریف نماییم.

همچنین، Zod می‌تواند داده‌های ورودی (که اغلب از پاسخ‌های API هستند) را اعتبارسنجی کند تا اطمینان حاصل شود که با این قوانین تطابق دارند. این فرآیند اعتبارسنجی تضمین می‌کند که داده‌ها از قالب تعریف‌شده تبعیت می‌کنند و در نتیجه، قابلیت اطمینان و یکپارچگی برنامه ما افزایش می‌یابد.

دلایل درخشش Zod در اعتبارسنجی API در React عبارت‌اند از:

با استفاده از Zod می‌توانیم پاسخ‌های غیرقابل پیش‌بینی API را به داده‌هایی تمیز و ساختارمند تبدیل کنیم و مسیر توسعه در React را برای خود هموارتر و مؤثرتر سازیم.

چگونه یک پروژه React با تایپ اسکریپت ایجاد کنیم؟

ایجاد یک پروژه جدید React با پشتیبانی از تایپ اسکریپت بسیار ساده است. کافیست دستور زیر را در ترمینال اجرا کنیم:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
npm create vite@latest my-react-app -- --template react-ts
npm create vite@latest my-react-app -- --template react-ts
npm create vite@latest my-react-app -- --template react-ts

پس از ایجاد پروژه، وارد پوشه آن می‌شویم و دستورات زیر را اجرا می‌کنیم:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
cd my-react-app
npm install
npm run dev
cd my-react-app npm install npm run dev
cd my-react-app
npm install
npm run dev

اکنون می‌توانیم از پروژه React خود با پشتیبانی از تایپ اسکریپت استفاده کنیم. برای نصب کتابخانه Zod، دستور زیر را اجرا می‌کنیم:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
npm install zod
npm install zod
npm install zod

بررسی مفاهیم اصلی کتابخانه Zod 

Zod با استفاده از اسکیمای داده‌ها به ما کمک می‌کند تا انتظارات روشنی برای پاسخ‌های API خود تعریف کنیم. این اسکیماها مانند نقشه‌هایی هستند که نوع داده‌هایی که انتظار دریافت آن‌ها را داریم، مشخص می‌کنند.

چگونه اسکیما بسازیم؟

Zod توابع سازنده‌ای مانند

z.string()
z.string()،
z.number()
z.number() و
z.object()
z.object() در اختیار ما قرار می‌دهد تا بتوانیم اسکیماهای خود را تعریف کنیم. این توابع مشخص می‌کنند که یک فیلد خاص در پاسخ API باید چه نوع داده‌ای داشته باشد:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import { z } from 'zod';
// Define basic data types
const userName = z.string().min(5).max(10); // String with min 5 and max 10 characters
const userAge = z.number().positive().int(); // Positive integer
const userEmail = z.string().email(); // Ensures a valid email format
console.log(userName.parse('John Doe')); // Output: John Doe (valid)
console.log(userAge.parse(30)); // Output: 30 (valid)
console.log(userEmail.parse("johnDoe@gmail.com")); // Output: johnDoe@gmail.com (valid)
import { z } from 'zod'; // Define basic data types const userName = z.string().min(5).max(10); // String with min 5 and max 10 characters const userAge = z.number().positive().int(); // Positive integer const userEmail = z.string().email(); // Ensures a valid email format console.log(userName.parse('John Doe')); // Output: John Doe (valid) console.log(userAge.parse(30)); // Output: 30 (valid) console.log(userEmail.parse("johnDoe@gmail.com")); // Output: johnDoe@gmail.com (valid)
import { z } from 'zod';
// Define basic data types
const userName = z.string().min(5).max(10); // String with min 5 and max 10 characters
const userAge = z.number().positive().int();  // Positive integer
const userEmail = z.string().email();        // Ensures a valid email format

console.log(userName.parse('John Doe'));       // Output: John Doe (valid)
console.log(userAge.parse(30));              // Output: 30 (valid)
console.log(userEmail.parse("johnDoe@gmail.com")); // Output: johnDoe@gmail.com (valid)

کد بالا سه نوع داده بیسیک را تعریف می‌کند:

چگونه قوانین اعتبارسنجی را اضافه کنیم؟

Zod به ما این امکان را می‌دهد تا با زنجیره‌سازی متدهایی مانند min، max، positive، int و email، قوانین خاصی را بر روی این نوع داده‌ها اعمال نماییم.

در ادامه، نمونه‌ای از رشته‌ای را می‌بینیم که از حداکثر تعداد کاراکتر مجاز عبور کرده است:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
console.log(userName.parse("Hello there, My Name is John Doe")); // Throws ZodError
console.log(userName.parse("Hello there, My Name is John Doe")); // Throws ZodError
console.log(userName.parse("Hello there, My Name is John Doe")); // Throws ZodError

کد فوق به دلیل تجاوز از حداکثر طول ۱۰ کاراکتر، یک

ZodError
ZodError ایجاد می‌کند. این خطا ممکن است جریان برنامه را مختل کند و در نهایت باعث شود برنامه از کار بیفتد.

اعتبارسنجی و تجزیه داده‌ها

Zod دو روش برای بررسی داده‌ها با استفاده از اسکیما ارائه می‌دهد:

مثال‌هایی برای استفاده از safeParse با داده‌های معتبر و نامعتبر

مثال اول: استفاده از safeParse با داده‌های معتبر

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const userSchema = z.object({
name: userName,
age: userAge,
email: userEmail,
});
const userData = {
name: "John Doe",
age: 24,
email: "johndoe@gmail.com"
};
const result = userSchema.safeParse(userData);
console.log(result); // ZodObject containing data and success status
const userSchema = z.object({ name: userName, age: userAge, email: userEmail, }); const userData = { name: "John Doe", age: 24, email: "johndoe@gmail.com" }; const result = userSchema.safeParse(userData); console.log(result); // ZodObject containing data and success status
const userSchema = z.object({
  name: userName,
  age: userAge,
  email: userEmail,
});

const userData = {
  name: "John Doe",
  age: 24,
  email: "johndoe@gmail.com"
};

const result = userSchema.safeParse(userData);

console.log(result); // ZodObject containing data and success status

در این مثال، یک اسکیمای کاربر با ویژگی‌های

name
name،
age
age و
email
email تعریف کرده‌ایم. سپس با استفاده از
safeParse()
safeParse() تلاش می‌کنیم آبجکت
userData
userData مطابق این اسکیما تجزیه شود. وقتی عملیات با موفقیت انجام می‌شود، کامپوننت داده تجزیه‌شده را نمایش می‌دهد. در غیر این صورت، پیغام خطا چاپ خواهد شد.

مثال دوم: استفاده از safeParse با داده‌های نامعتبر

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const userSchema = z.object({
name: userName,
age: userAge,
email: userEmail,
});
const userData = {
name: "John Doe",
age: 24,
email: "johndoe.com" // invalid email
};
const result = userSchema.safeParse(userData);
console.log(result); // ZodObject containing error and success status
const userSchema = z.object({ name: userName, age: userAge, email: userEmail, }); const userData = { name: "John Doe", age: 24, email: "johndoe.com" // invalid email }; const result = userSchema.safeParse(userData); console.log(result); // ZodObject containing error and success status
const userSchema = z.object({
  name: userName,
  age: userAge,
  email: userEmail,
});

const userData = {
  name: "John Doe",
  age: 24,
  email: "johndoe.com" // invalid email
};

const result = userSchema.safeParse(userData);

console.log(result); // ZodObject containing error and success status

در این مثال هم اسکیما مشابهی تعریف کرده‌ایم؛ اما این‌بار، عمداً داده‌ای نامعتبر (با فرمت نادرست ایمیل) را به تابع safeParse ارسال کرده‌ایم. بر خلاف متد

parse
parse که هنگام بروز خطا برنامه را متوقف می‌کند و خطای
ZodError
ZodError می‌دهد، متد
safeParse
safeParse امکان مدیریت خطا را به‌صورت ایمن و بدون توقف در اجرای برنامه فراهم می‌کند.

ساخت اسکیماهای Zod برای پاسخ‌های API

اکنون، با استفاده از مفاهیم اصلی Zod، اسکیماهایی طراحی می‌کنیم که به‌طور خاص برای داده‌های دریافتی از API کاربرد دارند. در اینجا از داده‌های سایت JSONPlaceholder استفاده می‌کنیم که اطلاعات مربوط به پست‌ها را در اختیارمان قرار می‌دهد.

نمونه‌ای از پاسخ JSON برای یک پست:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
{
"userId": 1,
"id": 3,
"title": "ea molestias quasi exercitationem repellat qui ipsa sit aut",
"body": "et iusto sed quo iure\nvoluptatem occaecati omnis eligendi aut"
}
{ "userId": 1, "id": 3, "title": "ea molestias quasi exercitationem repellat qui ipsa sit aut", "body": "et iusto sed quo iure\nvoluptatem occaecati omnis eligendi aut" }
{
  "userId": 1,
  "id": 3,
  "title": "ea molestias quasi exercitationem repellat qui ipsa sit aut",
  "body": "et iusto sed quo iure\nvoluptatem occaecati omnis eligendi aut"
}

ساخت یک کامپوننت React برای نمایش کاربرد Zod در اعتبارسنجی داده‌های API

برای اینکه نحوه استفاده از Zod در کنار API را نشان بدهیم، می‌توانیم یک کامپوننت React بسازیم. اسم کامپوننت را می‌توانیم مطابق ساختار پروژه خود انتخاب نماییم، اما در این مقاله، برای سادگی از اسم

ZodApi
ZodApi استفاده می‌کنیم.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import { z } from 'zod';
const postSchema = z.object({
userId: z.number().positive().int(),
id: z.number().positive().int(),
title: z.string(),
body: z.string()
});
const postSchemaArray = z.array(postSchema); // Schema for array of posts
import { z } from 'zod'; const postSchema = z.object({ userId: z.number().positive().int(), id: z.number().positive().int(), title: z.string(), body: z.string() }); const postSchemaArray = z.array(postSchema); // Schema for array of posts
 import { z } from 'zod';

  const postSchema = z.object({
  userId: z.number().positive().int(),
  id: z.number().positive().int(),
  title: z.string(),
  body: z.string()
});

const postSchemaArray = z.array(postSchema); // Schema for array of posts

در این قطعه کد:

نحوه اتصال Zod به API در React

اکنون می‌خواهیم اسکیماهایی که ساختیم را به داده‌های واقعی از API متصل کنیم و آن‌ها را اعتبارسنجی نماییم. برای این کار کدی که در بخش قبل نوشتیم را باید به‌روزرسانی کنیم:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import { z } from 'zod';
import { useEffect } from 'react';
const postSchema = z.object({
userId: z.number().positive().int(),
id: z.number().positive().int(),
title: z.string(),
body: z.string()
});
const postSchemaArray = z.array(postSchema); // schema for an array of posts
type Posts = z.infer<typeof postSchemaArray>; // type of the posts
const ZodApi = () => {
useEffect(() => {
fetch("https://jsonplaceholder.typicode.com/posts")
.then((response) => response.json())
.then((posts: Posts) => {
const validatedPosts = postSchemaArray.safeParse(posts); // remember to use safeParse instead of parse
if (validatedPosts.success === false) {
console.log("Validation Error:"validatedPosts.error);
return;
}
// we can now safely use the posts
console.log(validatedPosts.data);
});
}, []);
return <div>ZodApi</div>;
};
export default ZodApi;
import { z } from 'zod'; import { useEffect } from 'react'; const postSchema = z.object({ userId: z.number().positive().int(), id: z.number().positive().int(), title: z.string(), body: z.string() }); const postSchemaArray = z.array(postSchema); // schema for an array of posts type Posts = z.infer<typeof postSchemaArray>; // type of the posts const ZodApi = () => { useEffect(() => { fetch("https://jsonplaceholder.typicode.com/posts") .then((response) => response.json()) .then((posts: Posts) => { const validatedPosts = postSchemaArray.safeParse(posts); // remember to use safeParse instead of parse if (validatedPosts.success === false) { console.log("Validation Error:"validatedPosts.error); return; } // we can now safely use the posts console.log(validatedPosts.data); }); }, []); return <div>ZodApi</div>; }; export default ZodApi;
import { z } from 'zod';
import { useEffect } from 'react';

const postSchema = z.object({
  userId: z.number().positive().int(),
  id: z.number().positive().int(),
  title: z.string(),
  body: z.string()
});

const postSchemaArray = z.array(postSchema); // schema for an array of posts

type Posts = z.infer<typeof postSchemaArray>; // type of the posts

const ZodApi = () => {
  useEffect(() => {
    fetch("https://jsonplaceholder.typicode.com/posts")
      .then((response) => response.json())
      .then((posts: Posts) => {
        const validatedPosts = postSchemaArray.safeParse(posts); // remember to use safeParse instead of parse

        if (validatedPosts.success === false) {
          console.log("Validation Error:"validatedPosts.error);
          return;
        }

        // we can now safely use the posts
        console.log(validatedPosts.data);
      });
  }, []);
  return <div>ZodApi</div>;
};

export default ZodApi;

کامپوننت

ZodApi
ZodApi موارد زیر را بیان می‌کند:

نحوه رندر رابط کاربری و مدیریت خطا در React

در این بخش، یاد می‌گیریم چگونه داده‌های اعتبارسنجی‌شده را در رابط کاربری نمایش دهیم و با استفاده از stateهای React، مکانیزم مدیریت خطا را پیاده‌سازی کنیم.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import { z } from "zod";
import { useEffect, useState } from "react";
const postSchema = z.object({
userId: z.number().positive().int(),
id: z.number().positive().int(),
title: z.string(),
body: z.string(),
});
const postSchemaArray = z.array(postSchema); // schema for an array of posts
type Posts = z.infer<typeof postSchemaArray>; // type of the posts
const ZodApi = () => {
const [posts, setPosts] = useState<Posts>([]); // State to store validated posts
const [error, setError] = useState(""); // State to store any errors
useEffect(() => {
fetch("https://jsonplaceholder.typicode.com/posts")
.then((response) => response.json())
.then((posts: Posts) => {
const validatedPosts = postSchemaArray.safeParse(posts); // remember to use safeParse instead of parse
if (validatedPosts.success === false) {
console.log(validatedPosts.error.name);
setError(validatedPosts.error.message); // set error state
return;
}
// we can now safely use the validatedPosts
console.log(validatedPosts.data);
setPosts(validatedPosts.data)
});
}, []);
// Handle loading state (optional)
if (!posts.length && !error) {
return <div>Loading posts...</div>;
}
// Handle error state
if (error) {
return <div>Error fetching Data</div>; // Display user-friendly error message
}
return (
<div>
<h1>Posts</h1>
<ol>
{posts.map((post) => (
<li key={post.id}>
{post.title}
</li>
))}
</ol>
</div>
);
};
export default ZodApi;
import { z } from "zod"; import { useEffect, useState } from "react"; const postSchema = z.object({ userId: z.number().positive().int(), id: z.number().positive().int(), title: z.string(), body: z.string(), }); const postSchemaArray = z.array(postSchema); // schema for an array of posts type Posts = z.infer<typeof postSchemaArray>; // type of the posts const ZodApi = () => { const [posts, setPosts] = useState<Posts>([]); // State to store validated posts const [error, setError] = useState(""); // State to store any errors useEffect(() => { fetch("https://jsonplaceholder.typicode.com/posts") .then((response) => response.json()) .then((posts: Posts) => { const validatedPosts = postSchemaArray.safeParse(posts); // remember to use safeParse instead of parse if (validatedPosts.success === false) { console.log(validatedPosts.error.name); setError(validatedPosts.error.message); // set error state return; } // we can now safely use the validatedPosts console.log(validatedPosts.data); setPosts(validatedPosts.data) }); }, []); // Handle loading state (optional) if (!posts.length && !error) { return <div>Loading posts...</div>; } // Handle error state if (error) { return <div>Error fetching Data</div>; // Display user-friendly error message } return ( <div> <h1>Posts</h1> <ol> {posts.map((post) => ( <li key={post.id}> {post.title} </li> ))} </ol> </div> ); }; export default ZodApi;
import { z } from "zod";
import { useEffect, useState } from "react";

const postSchema = z.object({
  userId: z.number().positive().int(),
  id: z.number().positive().int(),
  title: z.string(),
  body: z.string(),
});

const postSchemaArray = z.array(postSchema); // schema for an array of posts

type Posts = z.infer<typeof postSchemaArray>; // type of the posts

const ZodApi = () => {
  const [posts, setPosts] = useState<Posts>([]); // State to store validated posts
  const [error, setError] = useState(""); // State to store any errors
  useEffect(() => {
    fetch("https://jsonplaceholder.typicode.com/posts")
      .then((response) => response.json())
      .then((posts: Posts) => {
        const validatedPosts = postSchemaArray.safeParse(posts); // remember to use safeParse instead of parse

        if (validatedPosts.success === false) {
          console.log(validatedPosts.error.name);
          setError(validatedPosts.error.message); // set error state
          return;
        }

        // we can now safely use the validatedPosts 
        console.log(validatedPosts.data);
        setPosts(validatedPosts.data)
      });
  }, []);

  // Handle loading state (optional)
  if (!posts.length && !error) {
    return <div>Loading posts...</div>;
  }

  // Handle error state
  if (error) {
    return <div>Error fetching Data</div>; // Display user-friendly error message
  }

  return (
    <div>
      <h1>Posts</h1>
      <ol>
        {posts.map((post) => (
          <li key={post.id}>
            {post.title}
          </li>
        ))}
      </ol>
    </div>
  );
};

export default ZodApi;

کدی که در اختیار داریم، مربوط به کامپوننت

ZodApi
ZodApi است که برای انجام وظایف مشخصی به‌روزرسانی شده است:

در نهایت، زمانی که فرآیند بارگذاری با موفقیت انجام شود، کاربران باید بتوانند ۱۰۰ پست را روی صفحه مشاهده کنند. اگر همه مراحل را به‌درستی طی کرده باشیم، این تعداد پست قابل نمایش خواهد بود. در غیر این صورت، لازم است بررسی کنیم که درخواست

fetch
fetch به‌درستی ارسال و پردازش می‌شود.

جمع‌بندی

با اضافه کردن Zod به روند توسعه React، می‌توانیم برنامه‌هایی مقاوم‌تر و قابل‌اعتمادتر بسازیم.

Zod این امکان را فراهم می‌کند تا ما در همان مراحل اولیه، ناسازگاری‌های داده‌ای را شناسایی کنیم و جلوی خطاهای پیچیده را بگیریم. این ویژگی موجب صرفه‌جویی در زمان اشکال‌زدایی و افزایش کیفیت کد خواهد شد.

همچنین، پیام‌های خطای قابل‌فهم و کاربرپسند Zod، تجربه کاربری را بهبود می‌بخشند و توسعه‌دهندگان را در شناسایی سریع‌تر مشکلات یاری می‌دهند.