نحوه استفاده از JSON Server برای توسعه فرانت‌اند

یکی از متداول‌ترین مسئولیت‌های توسعه‌دهندگان فرانت‌اند، مدیریت داده‌ها در برنامه‌های فرانت‌اندشان است. باید بتوانیم داده‌ها را از یک API بازیابی کنیم، بر روی آن‌ها تغییراتی ایجاد نماییم و سپس در یک برنامه وب مدرن برای تعامل با کاربر، روی صفحه نمایش دهیم.

وجود یک ارتباط کارآمد بین قسمت فرانت‌اند و بک‌اند برای ایجاد برنامه‌های یکپارچه و ریسپانسیو بسیار مهم است.

اکنون سناریویی را تصور می‌کنیم که در آن با یک توسعه‌دهنده بک‌اند بر روی یک پروژه کار می‌کنیم و منتظر API endpoint هستیم تا به فرانت‌اند خود متصل شویم. یک ابزار عالی وجود دارد که توسعه‌دهندگان فرانت‌اند می‌توانند از آن برای ایجاد یک API ساختگی در مرحله توسعه استفاده کنند. این ابزار JSON Server نام دارد.

در این مقاله قصد داریم تا نحوه استفاده از JSON serverها برای ذخیره‌سازی داده در برنامه‌های React را بررسی کنیم. همچنین با پیاده‌سازی یک پروژه فرانت‌اند، با ویژگی‌ها و مزایای آن بیشتر آشنا خواهیم شد.

برنامه‌ای که قصد داریم آن را پیاده‌سازی کنیم به کاربران این امکان را می‌دهد تا لیستی از کاربران و جزئیات اطلاعات آن‌ها را مشاهده کنند. داده‌های کاربر با استفاده از JSON server در یک فایل JSON در برنامه فرانت‌اند ایجاد می‌شود.

JSON Server چیست؟

JSON مخفف عبارت JavaScript Object Notation است و یک ابزار Node.js سبک و با کاربری آسان می‌باشد که یک API RESTful را با استفاده از یک فایل JSON به عنوان data source شبیه‌سازی می‌کند. توسعه‌دهندگان فرانت‌اند با کمک JSON Server می‌توانند APIهای ساختگی را بدون نیاز به نوشتن کدهای پیچیده سمت سرور یا زمانی که API پشتیبان هنوز آماده نیست ایجاد کنند.

این API ساختگی درخواست‌ها را به endpointای که ارائه خواهد شد ارسال می‌کند، به درخواست‌های HTTP پاسخ می‌دهد و به این ترتیب کار را برای توسعه سریع برای توسعه‌دهندگان فرانت‌اند ایده‌آل می‌کند. JSON Server همچنین توسعه‌دهندگان را قادر می‌سازد تا عملیات CRUD را انجام دهند و داده‌ها را در فایل‌های JSON ذخیره کنند. فایل JSON به عنوان مقادیر key-value و در قالب زیر نوشته می‌شود:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
{
"name": "Jane",
"age": 30,
"gender": "Female"
}
{ "name": "Jane", "age": 30, "gender": "Female" }
{  
  "name": "Jane",   
  "age": 30,   
  "gender": "Female"
}

به

name
name،
age
age و
gender
gender keyگفته می‌شود و
Jane
Jane،
۳۰
۳۰ و
female
female value هر یک از این keyها هستند.

فایل داده JSON می‌تواند در دو فرمت آرایه و آبجکت با آیجکت‌های تودرتو ارائه شود.

فرمت آرایه

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
[
{
"id": 1,
"name": "John Doe",
"age": 25
},
{
"id": 2,
"name": "Jane Smith",
"age": 40
}
]
[ { "id": 1, "name": "John Doe", "age": 25 }, { "id": 2, "name": "Jane Smith", "age": 40 } ]
[
  {
    "id": 1,
    "name": "John Doe",
    "age": 25
  },
  {
    "id": 2,
    "name": "Jane Smith",
    "age": 40
  }
]

فرمت آبجکت با آبجکت‌های تودرتو

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
{
"users": {
"۱": {
"name": "John Doe",
"age": 25
},
"۲": {
"name": "Jane Smith",
"age": 30
}
}
}
{ "users": { "۱": { "name": "John Doe", "age": 25 }, "۲": { "name": "Jane Smith", "age": 30 } } }
{
  "users": {
    "۱": {
      "name": "John Doe",
      "age": 25
    },
    "۲": {
      "name": "Jane Smith",
      "age": 30
    }
  }
}

ویژگی‌های JSON Server

در ادامه برخی از ویژگی‌های JSON Server را داریم که عبارتند از:

  • راه‌اندازی آن آسان و سریع است. همچنین استفاده از آن برای توسعه‌دهندگان فرانت‌اند و بک‌اند مبتدی ساده می‌باشد.
  • JSON Server درست مانند یک API server بک‌اند واقعی از متدهای رایج HTTP مانند متدهای
    GET
    GET،
    POST
    POST،
    PUT
    PUT و
    DELETE
    DELETE پشتیبانی می‌کند.
  • با استفاده از JSON Server، می‌توانیم عملیات
    Create
    Create،
    Read
    Read،
    Update
    Update و
    Delete
    Delete (CRUD) را روی داده‌ها انجام دهیم تا بتوانیم یک برنامه تعاملی بسازیم.
  • JSON Server امکان ایجاد مسیرهای سفارشی برای مدیریت سناریوهای پیچیده‌تر را به توسعه‌دهندگان ارائه می‌دهد.

مزایای استفاده از JSON Server

در این بخش به برخی از مزایای استفاده از JSON Server اشاره می‌کنیم که عبارتند از:

  • JSON Server این امکان را به توسعه‌دهندگان فرانت‌اند می‌دهد که به سرعت نمونه‌های اولیه API فانکشنال را ایجاد کنند. به این ترتیب، می‌توانند در حالی که منتظر آماده شدن سرور بک‌اند هستند، این نمونه‌ها را تست و اصلاح کنند.
  • توسعه‌دهندگان فرانت‌اند می‌توانند از JSON Server برای شبیه‌سازی سناریوهای مختلف و موارد خطا در حین تست برای بهبود برنامه خود استفاده نمایند.

روش راه‌اندازی JSON Server در یک برنامه

ما باید Node.js و npm را روی سیستم خود نصب کنیم، زیرا هر دو پیش نیاز این تنظیمات هستند. سپس مراحل زیر را برای راه‌اندازی و استفاده از JSON Server در برنامه فرانت‌اند خود دنبال می‌کنیم:

JSON Server را نصب می‌کنیم

برای نصب JSON Server در برنامه خود، به دایرکتوری پروژه خود در ترمینال یا خط فرمان می‌رویم و دستور زیر را تایپ می‌کنید:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
npm install -g json-server
npm install -g json-server
npm install -g json-server

با این کار JSON Server به صورت سراسری روی سیستم ما نصب می‌شود. اگر بخواهیم آن را به صورت محلی فقط برای یک پروژه خاص نصب کنیم، از دستور زیر استفاده می‌کنیم:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
npm i json-server
npm i json-server
npm i json-server

یک فایل JSON ایجاد می‌کنیم

یک فایل JSON در دایرکتوری پروژه خود ایجاد می‌کنید که به عنوان data source عمل می‌کند. این فایل JSON باید پسوند فایل

json.
json.داشته باشد. یعنی اگر بخواهیم نام فایل JSON ما
db
dbباشد، فایلی به نام
db.json
db.jsonایجاد می‌کنیم.

داده‌ها را می‌سازیم

داده‌های خود را در فایل JSON تعریف می‌کنیم. این داده‌های JSON می‌توانند آرایه‌ای از آبجکت‌ها یا یک آبجکت با آبجکت‌ها تودرتو باشند. هر آبجکت یک موجودیت داده را نشان می‌دهد که باید یک

id
id منحصربه‌فرد داشته باشد.

سرور را راه‌اندازی می‌کنیم

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

json-server --watch db.json
json-server --watch db.json. به طور پیش‌فرض روی آدرس
https://localhost:3000
https://localhost:3000اجرا می‌شود. هنگام راه‌اندازی سرور با استفاده از flag
--port
--port، می‌توانیم پورتی را که روی آن اجرا می‌شود، با تعیین شماره پورت دیگری تغییر دهیم.

به عنوان مثال، اگر بخواهیم سرور ما به جای پورت پیش‌فرض (۳۰۰۰) روی پورت ۸۰۰۰ اجرا شود، هنگام راه‌اندازی سرور باید از این دستور استفاده کنیم:

json-server --watch db.json --port 8000
json-server --watch db.json --port 8000. سپس می‌توانیم آن را در مرورگر خود روی پورت ۸۰۰۰ مشاهده نماییم.

JSON Server به طور خودکار endpointهای RESTful را بر اساس داده‌هایی که در فایل JSON خود تعریف کرده‌ایم، ایجاد می‌کند.

اگر یک فایل JSON با آرایه‌ای از

users
users داریم، این endpoint است که به طور خودکار توسط JSON Server ایجاد می‌شود:

  • GET /users
    GET /users– فهرستی از تمام موجودیت‌های منابع کاربران را بازیابی می‌کند.
  • GET /users/:id
    GET /users/:id– یک کاربر خاص را با
    id
    id خود بازیابی می‌کند.
  • POST /users
    POST /users– یک کاربر جدید ایجاد می‌کند.
  • PUT /users/:id
    PUT /users/:id– یک کاربر را بر اساس
    id
    id مشخص شده به‌روزرسانی می‌کند.
  • DELETE /users/:id
    DELETE /users/:id– یک کاربر را بر اساس
    id
    id مشخص شده حذف می‌کند.

این الگو تعامل با API ساختگی را به روش RESTful و درست مانند API واقعی بک‌اند انجام می‌دهد.

نحوه ساخت یک برنامه فرانت‌اند ساده با استفاده از JSON Server

برای درک بیشتر نحوه استفاده از JSON Server در یک پروژه واقعی، یک مثال را باهم بررسی می‌کنیم. ما یک برنامه ساده React.js خواهیم ساخت که داده‌های کاربران را از یک فایل داده JSON با استفاده از JSON Server در قسمت فرانت‌اند نمایش می‌دهد.

این برنامه فقط دو صفحه خواهد داشت. صفحه اول لیستی از کاربران همراه با نام و آدرس ایمیل آن‌ها را دربرمی‌گیرد. با کلیک روی دکمه مشاهده جزئیات کامل، وارد صفحه دیگری می‌شویم که جزئیات بیشتر در مورد هر کاربر را بر اساس

id
id کاربری آن، نمایش می‌دهد.

نصب dependencyها

با استفاده Vite یک برنامه React ایجاد می‌کنیم. برای انجام این کار دستور زیر را اجرا می‌نماییم:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
yarn create vite
yarn create vite
yarn create vite

نام پروژه را انتخاب کرده و React را به عنوان فریم‌ورک و تایپ اسکریپت را به عنوان variant انتخاب می‌کنیم. در صورت تمایل می‌توانیم از جاوااسکریپت هم به عنوان variant استفاده کنیم.

پس از انجام این کار، به پروژه خود می‌رویم و با کمک دستور

yarn
yarn نصب dependencyها را انجام می‌دهیم. پس از اینکه dependencyها را با موفقیت نصب کردیم، سرور توسعه خود را با این دستور اجرا می‌کنیم:
yarn run dev
yarn run dev. مرورگر خود را باز کرده و URL (
http://127.0.0.1:5173/
http://127.0.0.1:5173/) را جایگذاری می‌نماییم و به این ترتیب، برنامه در حال اجرا خود را در مرورگر مشاهده می‌کنیم.

با استفاده از دستور زیر JSON server را در برنامه خود نصب می‌کنید:

برای نصب سراسری:

npm install -g json-server
npm install -g json-server

برای نصب محلی:

npm i json-server
npm i json-server

آخرین پکیجی که نصب می‌کنیم react-router است تا با استفاده از آن، از page navigation بهره‌مند شویم:

npm i react-router-dom
npm i react-router-dom.

بررسی ساختار پوشه

اکنون می‌خواهیم برنامه‌ای که داریم ساختار پوشه‌ای مرتب داشته باشد، بنابراین این دستورالعمل‌ها را دنبال می‌کنیم:

ابتدا یک پوشه

data
data در دایرکتوری root پروژه خود می‌سازیم. در داخل این پوشه
data
data، یک فایل JSON به نام
db.json
db.json ایجاد می‌کنیم. این فایل جایی است که داده‌های JSON تعریف می‌شوند.

سپس، در دایرکتوری src، یک پوشه

components
components ایجاد می‌کنیم. در این پوشه ۳ فایل
Home.tsx
Home.tsx،
UserDetails.tsx
UserDetails.tsx و
UserList.tsx
UserList.tsx را می‌سازیم. این‌ها کامپوننت‌هایی هستند که منطق و رابط کاربری برنامه را رندر می‌کنند.

در دایرکتوری src یک فایل با نام

useFetch.tsx
useFetch.tsx ایجاد می‌کنیم. این فایل حاوی کد اجرای API خواهد بود. کامپوننت اصلی برنامه ما، یعنی فایل
App.tsx
App.tsx جایی است که ما مسیریابی صفحات را در آن مدیریت خواهیم کرد.

شروع ساخت برنامه

اولین کامپوننتی که باید تغییراتی را در آن ایجاد کنیم فایل

App.tsx
App.tsx است. خطوط کد زیر را در کامپوننت قرار می‌دهیم:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import Home from './components/Home';
import UserDetails from './components/UserDetails';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
function App() {
return (
<Router>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/users/:id" element={<UserDetails />} />
</Routes>
</Router>
)
}
export default App
import Home from './components/Home'; import UserDetails from './components/UserDetails'; import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; function App() { return ( <Router> <Routes> <Route path="/" element={<Home />} /> <Route path="/users/:id" element={<UserDetails />} /> </Routes> </Router> ) } export default App
import Home from './components/Home';
import UserDetails from './components/UserDetails';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';

function App() {
  return (
    <Router>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/users/:id" element={<UserDetails />} />
      </Routes>
    </Router>
  )
}

export default App

این فایل فقط برای رندر مسیرهایی برای برنامه است.

به فایل

db.json
db.json می‌رویم و داده‌های JSON خود را در داخل آن تعریف می‌کنیم:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
{
"users": [
{
"id": 1,
"name": "Juliet Oma",
"email": "julie@yahoo.com",
"number": "08100000000"
},
{
"id": 2,
"name": "James Williams",
"email": "jameswilly@gmail.com",
"number": "08111111111"
},
{
"id": 3,
"name": "Ahmed Ali",
"email": "ahmedali012@gmail.com",
"number": "09022222222"
},
{
"id": 4,
"name": "Grace Funsho",
"email": "gracefunsho@gmail.com",
"number": "09033333333"
}
]
}
{ "users": [ { "id": 1, "name": "Juliet Oma", "email": "julie@yahoo.com", "number": "08100000000" }, { "id": 2, "name": "James Williams", "email": "jameswilly@gmail.com", "number": "08111111111" }, { "id": 3, "name": "Ahmed Ali", "email": "ahmedali012@gmail.com", "number": "09022222222" }, { "id": 4, "name": "Grace Funsho", "email": "gracefunsho@gmail.com", "number": "09033333333" } ] }
{
  "users": [
    {
      "id": 1,
      "name": "Juliet Oma",
      "email": "julie@yahoo.com",
      "number": "08100000000"
    },
    {
      "id": 2,
      "name": "James Williams",
      "email": "jameswilly@gmail.com",
      "number": "08111111111"
    },
    {
      "id": 3,
      "name": "Ahmed Ali",
      "email": "ahmedali012@gmail.com",
      "number": "09022222222"
    },
    {
      "id": 4,
      "name": "Grace Funsho",
      "email": "gracefunsho@gmail.com",
      "number": "09033333333"
    }
  ]
}

server خود را با استفاده از دستور زیر راه‌اندازی می‌کنیم:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
json-server --watch db.json --port 8000
json-server --watch db.json --port 8000
json-server --watch db.json --port 8000

این دستور فایل

db.json
db.json را مشاهده می‌کند و API endpointای را که روی پورت ۸۰۰۰ اجرا می‌شود، درون آن قرار می‌دهد.

اگر URL (

http://localhost:8000/users
http://localhost:8000/users) ارائه شده در ترمینال را کپی کنیم و آن را در مرورگر خود باز نماییم، یک داده JSON خواهیم دید که تمام داده‌های کاربری را که در فایل
db.json
db.json خود تعریف کرده‌ایم به نمایش می‌گذارد.

در مرحله بعد، باید برای پیاده‌سازی API کدنویسی انجام دهیم. این کار را در فایل

useFetch.tsx
useFetch.tsx انجام خواهیم داد. این فایل اساساً یک هوک سفارشی React است که برای مدیریت دریافت داده‌های asynchronous از یک URL مشخص، ایجاد می‌کنیم.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import { useState, useEffect } from 'react';
interface UseFetchResult {
data: any | null;
isPending: boolean;
error: any | null;
}
const useFetch = (url: string): UseFetchResult => {
const [data, setData] = useState<any | null>(null);
const [isPending, setIsPending] = useState<boolean>(true);
const [error, setError] = useState<any | null>(null);
useEffect(() => {
setTimeout(() => {
fetch(url)
.then(res => {
if (!res.ok) {
throw Error('Error fetching users data');
}
return res.json();
})
.then(data => {
setData(data);
setIsPending(false);
setError(null);
})
.catch(err => {
setIsPending(false);
setError(err.message);
});
}, ۱۰۰۰);
}, [url]);
return { data, isPending, error };
}
export default useFetch;
import { useState, useEffect } from 'react'; interface UseFetchResult { data: any | null; isPending: boolean; error: any | null; } const useFetch = (url: string): UseFetchResult => { const [data, setData] = useState<any | null>(null); const [isPending, setIsPending] = useState<boolean>(true); const [error, setError] = useState<any | null>(null); useEffect(() => { setTimeout(() => { fetch(url) .then(res => { if (!res.ok) { throw Error('Error fetching users data'); } return res.json(); }) .then(data => { setData(data); setIsPending(false); setError(null); }) .catch(err => { setIsPending(false); setError(err.message); }); }, ۱۰۰۰); }, [url]); return { data, isPending, error }; } export default useFetch;
import { useState, useEffect } from 'react';

interface UseFetchResult {
    data: any | null;
    isPending: boolean;
    error: any | null;
}

const useFetch = (url: string): UseFetchResult => {
    const [data, setData] = useState<any | null>(null);
    const [isPending, setIsPending] = useState<boolean>(true);
    const [error, setError] = useState<any | null>(null);

    useEffect(() => {
        setTimeout(() => {
            fetch(url)
                .then(res => {
                    if (!res.ok) {
                        throw Error('Error fetching users data');
                    }
                    return res.json();
                })
                .then(data => {
                    setData(data);
                    setIsPending(false);
                    setError(null);
                })
                .catch(err => {
                    setIsPending(false);
                    setError(err.message);
                });
        }, ۱۰۰۰);
    }, [url]);

    return { data, isPending, error };
}

export default useFetch;

تحلیل کد

ابتدا هوک‌های

useState
useState و useEffect را import می‌کنیم تا از آن‌ها برای مدیریت stateها و انجام side effectها در هوک سفارشی استفاده کنیم.

هنگام تنظیم پروژه، تایپ اسکریپت را به عنوان یک variant انتخاب کردیم. بنابراین، باید یک interface به نام

useFetchResult
useFetchResult تعریف کنیم تا ساختار آبجکت نتیجه‌ای را که هوک
useFetch
useFetch return می‌کند را مشخص نماید. این interface شامل سه ویژگی است:
data
data،
isPending
isPending و
error
error.

کد

const useFetch = (url: string): UseFetchResult => { ... }
const useFetch = (url: string): UseFetchResult => { ... } هوک سفارشی
useFetch
useFetch را تعریف می‌کند. یک پارامتر
url
url از نوع رشته می‌گیرد و یک آبجکت برمی‌گرداند که با اینترفیس
UseFetchResult
UseFetchResult مطابقت دارد.

در مرحله بعد، باید با استفاده از هوک

useState
useState سه متغیر را مقداردهی اولیه کنیم:
data
data برای ذخیره داده‌های دریافت شده،
isPending
isPending برای نشان دادن اینکه آیا دریافت داده در حال انجام است یا خیر و state
error
error برای ذخیره هر گونه خطایی که در طول فرآیند دریافت رخ می‌دهد. هر کدام به ترتیب دارای مقدار اولیه
null
null،
true
true و
null
null هستند.

هوک

useEffect
useEffect برای دریافت داده‌ها هنگام تغییر URL استفاده می‌شود. این هوک پس از رندر اولیه و هر زمان که وابستگی URL تغییر کند، اجرا می‌شود. در داخل تابع
useEffect
useEffect، یک
setTimeOut
setTimeOut برای شبیه‌سازی یک تاخیر ۱۰۰۰ میلی ثانیه‌ای (۱ ثانیه) قبل از شروع دریافت داده‌ها تعریف شده است.

از متد

fetch
fetch برای درخواست
GET
GET به URl مشخص شده استفاده می‌شود. responseای که برمی‌گردد با استفاده از
res.ok
res.ok بررسی می‌شود. اگر ok نباشد، خطا رخ می‌دهد. سپس response با استفاده از متد
res.json()
res.json() به JSON تبدیل شده و در متغیر
data
data ذخیره می‌شود. state
isPending
isPending روی
false
false تنظیم می‌شود تا نشان دهد دریافت داده‌ها کامل شده است و state
error
error روی
null
null تنظیم می‌شود تا خطای قبلی پاک شود.

اگر در طول فرآیند دریافت داده‌ها خطایی رخ دهد، در بلاک

.catch
.catch ثبت می‌شود.
isPending
isPending روی
false
false تنظیم می‌شود و سپس state
error
error با پیام خطا به‌روزرسانی می‌گردد.

هوک سفارشی یک آبجکت حاوی

data
data،
isPending
isPending و stateهای
error
error را return می‌کند و به کامپوننت‌های دیگر اجازه می‌دهد تا به داده دریافت شده و state آن دسترسی داشته باشند.

ساخت لیست کاربران به صورت جدول

UserList.tsx
UserList.tsx کامپوننتی است که تمام اطلاعات کاربر را در یک جدول نمایش می‌دهد. در فایل
UserList.tsx
UserList.tsx خود، کد زیرا را می‌نویسیم:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import React from 'react';
import { Link } from 'react-router-dom';
interface User {
id: number;
name: string;
email: string;
number: string;
}
interface UserListProps {
users: User[];
name: string;
}
const UserList: React.FC<UserListProps> = ({ users, name }) => {
return (
<>
<section>
<section>
<h1>Users List</h1>
</section>
<section>
<table>
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>Details</th>
</tr>
</thead>
<tbody>
{users.map((user) => (
<tr key={user.id}>
<td>
<p>{user.name}</p>
</td>
<td>
<p>{user.email}</p>
</td>
<td>
<Link to={`/users/${user.id}`}>
<button>
View full details
</button>
</Link>
</td>
</tr>
))}
</tbody>
</table>
</section>
</section>
</>
);
};
export default UserList;
import React from 'react'; import { Link } from 'react-router-dom'; interface User { id: number; name: string; email: string; number: string; } interface UserListProps { users: User[]; name: string; } const UserList: React.FC<UserListProps> = ({ users, name }) => { return ( <> <section> <section> <h1>Users List</h1> </section> <section> <table> <thead> <tr> <th>Name</th> <th>Email</th> <th>Details</th> </tr> </thead> <tbody> {users.map((user) => ( <tr key={user.id}> <td> <p>{user.name}</p> </td> <td> <p>{user.email}</p> </td> <td> <Link to={`/users/${user.id}`}> <button> View full details </button> </Link> </td> </tr> ))} </tbody> </table> </section> </section> </> ); }; export default UserList;
import React from 'react';
import { Link } from 'react-router-dom';

interface User {
    id: number;
    name: string;
    email: string;
    number: string;
}

interface UserListProps {
    users: User[];
    name: string;
}

const UserList: React.FC<UserListProps> = ({ users, name }) => {

    return (
        <>
            <section>
                    <section>
                        <h1>Users List</h1>
                    </section>
                    <section>
                        <table>
                            <thead>
                                <tr>
                                    <th>Name</th>
                                    <th>Email</th>
                                    <th>Details</th>
                                </tr>
                            </thead>
                            <tbody>
                                {users.map((user) => (
                                    <tr key={user.id}>
                                        <td>
                                          <p>{user.name}</p>
                                        </td>

                                        <td>
                                            <p>{user.email}</p>
                                        </td>

                                        <td>
                                            <Link to={`/users/${user.id}`}>
                                                <button>
                                                    View full details
                                                </button>
                                            </Link>
                                        </td>
                                    </tr>
                                ))}
                            </tbody>
                        </table>
                    </section>
            </section>
        </>
    );
};

export default UserList;

کار خود را با import کردن

Link
Link از کتابخانه
react-router-dom
react-router-dom شروع می‌کنیم.

خط بعدی کد interface

User
User است، یک interface تایپ اسکریپ که ساختار یک آبجکت کاربر را تعریف می‌کند که دارای چهار ویژگی است و  هر ویژگی دارای یک نوع داده مشخص می‌باشد.

سپس interface 

UserListProps
UserListProps را داریم که ساختار یک آبجکت را تعریف می‌کند که دارای دو ویژگی
user
user و
name
name است.
users
users آرایه‌ای از آبجکت‌ها است که با interface
User
User مطابقت دارد.

این کامپوننت یک آبجکت با interface 

userListProps
userListProps را به عنوان آرگومان می‌گیرد،
users
users را از آن destruct کرده و به عنوان props در کامپوننت استفاده می‌کند.

پس از آن، المنت JSX را برای نمایش لیست کاربران در قالب جدول داریم. ما با استفاده از متد

map
map بر روی
users
users هر کاربر را در یک ردیف رندر می‌کنیم.

سپس یک دکمه به هر ردیف اضافه می‌کنیم که عمل navigation را به یک مسیر خاص (

/users/${user.id}
/users/${user.id}) انجام می‌دهد. این مسیرها اطلاعات دقیق کاربری را که
id
id او به عنوان بخشی از URL ارائه شده است، نمایش می‌دهد.

ما از یک قالب literal برای ایجاد یک URL داینامیک که شامل مقدار

user.id
user.id است استفاده کردیم.

نمایش لیست کاربران در مرورگر

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

Home.tsx
Home.tsx است. این همان جایی است که لیست کاربران بر روی صفحه، نمایش داده می‌شود و صفحه اصلی برنامه ما به حساب می‌آید.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import UserList from './UserList';
import useFetch from '../useFetch';
const Home = (): JSX.Element => {
const { data: users, isPending, error } = useFetch('http://localhost:8000/users')
return (
<section>
{error && <p>{error}</p>}
{isPending && <p>Loading users...</p>}
{users && <UserList users={users} />}
</section>
);
};
export default Home;
import UserList from './UserList'; import useFetch from '../useFetch'; const Home = (): JSX.Element => { const { data: users, isPending, error } = useFetch('http://localhost:8000/users') return ( <section> {error && <p>{error}</p>} {isPending && <p>Loading users...</p>} {users && <UserList users={users} />} </section> ); }; export default Home;
import UserList from './UserList';
import useFetch from '../useFetch';

const Home = (): JSX.Element => {
    const { data: users, isPending, error } = useFetch('http://localhost:8000/users')

    return (
        <section>
            {error && <p>{error}</p>}
            {isPending && <p>Loading users...</p>}
            {users && <UserList users={users} />}
        </section>
    );
};

export default Home;

ابتدا کامپوننت

UserList
UserList و هوک سفارشی
useFetch
useFetch را از جایی که در دایرکتوری پروژه قرار دارند import می‌کنیم.

خط کد

const { data: users, isPending, error } = useFetch('http://localhost:8000/users')
const { data: users, isPending, error } = useFetch('http://localhost:8000/users') هوک سفارشی
useFetch
useFetch را برای دریافت داده‌ها از URL مشخص شده فراخوانی می‌کند (
http://localhost:8000/users
http://localhost:8000/users). هوک یک آبجکت با سه ویژگی return می‌کند:
data
data(کاربران دریافت شده)،
isPending
isPending(وضعیت لود) و
error
error(پیام خطا).

ما رابط کاربری را با المنت‌های JSX رندر کردیم. اگر state

error
error دارای یک مقدار باشد، یک المنت پاراگراف حاوی پیام خطا را رندر می‌کند. اگر state
isPending
isPending مقدار
true
true داشته باشد، یک المنت پاراگراف را نمایش می‌دهد که نشان می‌دهد
users
users در حال بارگیری است. درنهایت اگر state
users
users داده‌ای داشته باشد (یعنی
null
null نباشد)، کامپوننت
UserList
UserList را رندر می‌کند و داده‌های کاربران را به عنوان prop ارسال می‌نماید.

نمایش اطلاعات کامل کاربران

ما می‌خواهیم یک functionality اضافی به برنامه خود بیافزاییم که در آن می‌توانید بر روی دکمه مشاهده جزئیات کامل که در همان ردیف با نام کاربر قرار دارد کلیک کنیم و جزئیات بیشتری را در مورد آن کاربر خاص در صفحه دیگری مشاهده نماییم. در کامپوننت

Userdetails.tsx
Userdetails.tsx کد زیر را داریم:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import { useParams } from 'react-router-dom';
import useFetch from '../useFetch';
const UserDetails = () => {
const { id } = useParams();
const { data: user, error, isPending } = useFetch("http://localhost:8000/users/" + id);
return (
<>
<section>
{isPending && <p>Loading user details...</p>}
{error && <p>{error}</p>}
{user && (
<>
<h1>User {user.id} details</h1>
<h2>{user.name}</h2>
<p>{user.email}</p>
<p>{user.number}</p>
</>
)}
</section>
</>
);
};
export default UserDetails;
import { useParams } from 'react-router-dom'; import useFetch from '../useFetch'; const UserDetails = () => { const { id } = useParams(); const { data: user, error, isPending } = useFetch("http://localhost:8000/users/" + id); return ( <> <section> {isPending && <p>Loading user details...</p>} {error && <p>{error}</p>} {user && ( <> <h1>User {user.id} details</h1> <h2>{user.name}</h2> <p>{user.email}</p> <p>{user.number}</p> </> )} </section> </> ); }; export default UserDetails;
import { useParams } from 'react-router-dom';
import useFetch from '../useFetch';

const UserDetails = () => {
    const { id } = useParams();
    const { data: user, error, isPending } = useFetch("http://localhost:8000/users/" + id);

    return (
        <>
            <section>
                {isPending && <p>Loading user details...</p>}

                {error && <p>{error}</p>}

                {user && (
                    <>
                        <h1>User {user.id} details</h1>
                        <h2>{user.name}</h2>
                        <p>{user.email}</p>
                        <p>{user.number}</p>
                    </>
                )}
            </section>
        </>
    );
};

export default UserDetails;

هوک

useParams
useParams را از کتابخانه
react-router-dom
react-router-dom import می‌کنیم. این هوک امکان دسترسی به پارامترهای URL را برای ما فراهم می‌کند. همچنین هوک سفارشی
useFetch
useFetch را هم import می‌کنیم.

const { id } = useParams();
const { id } = useParams(); از هوک
useParams
useParams برای استخراج پارامتر
id
id از URL استفاده می‌کند. این کد معمولاً در مسیرهایی مانند
/users/:id
/users/:id مورد استفاده قرار می‌گیرد.

در خط بعدی، هوک سفارشی

useFetch
useFetch را برای دریافت داده‌ها از URL یک کاربر خاص بر اساس پارامتر
id
id استخراج شده، فراخوانی می‌کند. هوک یک آبجکت با ویژگی های
data
data،
error
error و
isPending
isPending را return می‌کند.

سپس المنت‌های JSX می‌آیند تا جزئیات کاربران را رندر کنند.

{isPending && <p>Loading user details...</p>}
{isPending && <p>Loading user details...</p>} یک پاراگراف رندر می‌کند که نشان می‌دهد در صورتی که
isPending
isPending مقدار
true
true داشته باشد، جزئیات کاربر بارگیری می‌شود.

اگر خطایی وجود داشته باشد،

{error && <p>{error}</p>}
{error && <p>{error}</p>} یک پاراگراف را نمایش می‌دهد که پیام خطا را در آن به نمایش می‌گذارد. در حالی که
{user && (...)}
{user && (...)} برخی از جزئیات کاربر مانند
id
id،
name
name،
email
email و
number
number را در صورت موجود بودن داده‌ها رندر می‌کند.

هنگامی که به مرورگر خود بازگردیم، لیستی از داده‌های کاربر را در یک جدول مشاهده خواهیم کرد. هر ردیف کاربر در جدول دارای دکمه‌ای است که می‌توانیم روی آن کلیک کنیم تا صفحه‌ای برای ما باز شود و جزئیات کامل آن کاربر خاص را ببینیم.

پس از استایل‌دهی برنامه، یک دمو از آن را در این لینک داریم.

همینطور می‌توانیم داده‌های کاربر را تغییر دهیم یا جزئیات بیشتری مانند توضیحات شغل کاربران، عنوان آن‌ها و غیره را در فایل

db.json
db.json خود به لیست کاربران خود اضافه کنیم و تغییرات را در فهرست مرورگر مشاهده نماییم.

جمع‌بندی

در این مقاله سعی کردیم تا با JSON server و نحوه استفاده از آن در یک برنامه React.js فرانت‌اند آشنا شویم.

همچنین می‌توانیم عملیات CRUD کامل را با این داده‌ها از فایل JSON خود در قسمت فرانت‌اند برنامه‌ای که داریم انجام دهیم. ما در این مقاله فقط عملیات Read را بررسی کردیم.

همینطور مثالی که باهم بررسی کردیم، درخواستی را به API endpoint ارائه شده هنگام راه‌اندازی JSON server ارسال می‌کند و پاسخ را در مرورگر نمایش می‌دهد. این اساساً نحوه عملکرد یک API server بک‌اند واقعی است. در این مثال، ما توانستیم با استفاده از JSON server به فانکشنالیتی مورد نظر خود دست پیدا کنیم.

مهم است بدانیم که این API ساختگی JSON را نمی‌توانیم در مرحله تولید مورد استفاده قرار دهیم. فقط در مرحله توسعه برای ایجاد داده‌های ساختگی JSON قابل استفاده می‌باشد. این بدان معناست که ما نمی‌توانیم آن را به پروژه نهایی ارسال کنیم زیرا فایل داده JSON فقط بر روی یک پورت localhost اجرا می‌شود.

دیدگاه‌ها:

افزودن دیدگاه جدید