نحوه پیاده سازی Dynamic Segments با useParams در React Router
در یک وب سایت سنتی، زمانی که کاربر روی یک URL کلیک می کند، مرورگر یک درخواست تمام صفحه از سرور ارسال می کند و کاربر را به صفحه جدیدی هدایت می کند. این به عنوان مسیریابی استاتیک نامیده می شود.
اگر فقط نیاز دارید کاربر را به صفحه جدیدی هدایت کنید، این بسیار مفید است. اما با توسعه برنامه های وب، نیاز بیشتری به صفحات برای رندر کردن روی مشتری یا بارگذاری پویا وجود دارد.
این شامل بهروزرسانی بخشهای خاصی از URL به نام بخشها، و همچنین ارائه محتوای جدید یا بهروزرسانی محتوا در همان صفحه بدون درخواست از سرور یا بارگیری مجدد کل صفحه است.
این در برنامه های وب مدرن بسیار رایج و مفید است. این رندر سمت کلاینت را فعال میکند، ناوبری وبسایت را بهبود میبخشد و انتقال و انیمیشنهای صاف را فعال میکند (زیرا مرورگر نیازی به بارگیری مجدد صفحه از سرورهای خارجی ندارد).
این به طور کلی می تواند عملکرد وب سایت را بهبود بخشد و تجربه کاربری خوبی را ایجاد کند.
در این آموزش با Dynamic Segments در React Router آشنا خواهید شد.
ما به این خواهیم پرداخت که مسیریابی پویا چیست و چه تفاوتی با مسیریابی استاتیک دارد. همچنین نحوه استفاده از useParams برای فعال کردن بخشهای پویا و نحوه تنظیم مسیر خود را هنگام دریافت دادهها از یک API پوشش خواهیم داد.
در نهایت، ما یک پروژه جدید می سازیم که وقتی کاربر روی نوار کناری کلیک می کند، محتوای جدید را به صورت پویا در همان صفحه نمایش می دهد.
در پایان این راهنما، باید بتوانید بخش های پویا را به تنهایی در برنامه React خود پیاده سازی کنید.
فهرست مطالب
React Router را نصب کنید
نماد Feather را نصب کنید
Tailwind CSS را نصب کنید
نحوه ایجاد و استایل نوار ناوبری
پیش نیازها
برای پیگیری، به دانش اولیه در مورد موارد زیر نیاز دارید:
واکنش نشان دهید
React-Router
Tailwind CSS (اختیاری)
راه اندازی پروژه
برای شروع، یک پوشه به نام dynamic-segment
ایجاد کنید و آن را در VS Code (یا ویرایشگر کد انتخابی خود) باز کنید:
در مرحله بعد، روی Ctrl +
(بک تیک) کلیک کنید تا ترمینال همانطور که در بالا نشان داده شد راه اندازی شود. این به ما امکان می دهد بسته های npm را که در این پروژه استفاده می کنیم نصب کنیم.
تاسیسات
اکنون که پروژه خود را راه اندازی کرده ایم، بیایید بسته های npm
را که برای راه اندازی پروژه خود نیاز داریم نصب کنیم.
React را نصب کنید
React یک کتابخانه جاوا اسکریپت برای ساخت اجزای قابل استفاده مجدد و تعاملی است. برای نصب آن، دستور ارائه شده توسط vite.js را در زیر کپی و پیست کنید.
npm create vite@latest
سپس فقط راهنمای نصب را دنبال کنید تا فرآیند به پایان برسد. پس از اتمام نصب، پوشه node_modules باید در پوشه پروژه شما وجود داشته باشد.
React Router را نصب کنید
این یک کتابخانه مسیریابی React برای ایجاد برنامه های مسیریابی سمت مشتری است. برای نصب آن دستور زیر را کپی و پیست کرده و enter را فشار دهید.
npm i react-router-dom
نماد Feather را نصب کنید
نماد Feather یک مجموعه کوچک و در عین حال زیبا از آیکونهای منبع باز شبکهای ۲۴×۲۴ است. این برای گفت ن آیکون های مسطح در برنامه های وب ساخته شده است.
برای نصب آن دستور زیر را پیست کرده و enter را فشار دهید.
npm i react-feather
Tailwind CSS را نصب کنید
Tailwind اولین فریم ورک CSS کاربردی برای ساخت طراحی های زیبا و فشرده وب سایت است. برای نصب آن، دستور را در ترمینال زیر اجرا کنید.
npm install -D tailwindcss postcss autoprefixer
با این کار یک فایل tailwind.config.js
ایجاد می شود. سپس فایل های postcss.config.js
خود را با دستور زیر تولید کنید:
npx tailwindcss init -p
در مرحله بعد، مسیرهای قالب خود را پیکربندی کنید و مسیرها را به همه فایل های قالب خود در فایل tailwind.config.js
خود اضافه کنید. سپس برای ذخیره روی ctrl + s
کلیک کنید.
/** @type {import('tailwindcss').Config} */ export default { content: [ "./index.html", "./src/**/*.{js,ts,jsx,tsx}", ], theme: { extend: {}, }, plugins: [], }
سپس، تمام استایلهای CSS را در فایل ./src/index.css
حذف کنید و دستورات Tailwind @tailwind
برای هر یک از لایههای Tailwind اضافه کنید.
@tailwind base; @tailwind components; @tailwind utilities;
سپس پوشه assets
، فایل های App.css
و App.jsx
را از پوشه /src
حذف کنید. هنگامی که این کار را انجام دادید، فایل های main.jsx
را به عنوان جزء مسیر پیکربندی کنید، همانطور که در زیر نشان داده شده است:
import React from 'react' import ReactDOM from 'react-dom/client' import './index.css'; import { RouterProvider, createBrowserRouter, createRoutesFromElements, Route } from 'react-router-dom'; const router = createBrowserRouter( createRoutesFromElements( <Route> <Route path='/' element={<p className='text-blue-700'>Hello, world</p>}></Route> </Route> ) ) ReactDOM.createRoot(document.getElementById('root')).render( <React.StrictMode> <RouterProvider router={router} /> </React.StrictMode>, )
سپس دستور زیر را در ترمینال اجرا کنید تا برنامه شما راه اندازی شود:
npm run dev
برنامه شما باید در مرورگر شما به این شکل باشد:
مسیریابی سمت مشتری
در React Router، پیمایش بین صفت path
و ویژگی to
نسبی است. هنگامی که کاربر با استفاده از کامپوننت <Link>
( <a>
) کلیک می کند، به path
مشخص شده در مولفه مسیر حرکت می کند و زمانی که مؤلفه مطابقت دارد، آن را رندر می کند.
به این نوع پیمایش، مسیریابی سمت سرویس گیرنده گفته میشود، زیرا ما صفحات را از سرور رندر نمیکنیم، بلکه از یک مؤلفه به مؤلفه دیگر در برنامه پیمایش میکنیم.
مثال زیر نحوه عملکرد مسیریابی سایدینگ کلاینت را توضیح می دهد:
⚠️ //main.jsx import React from 'react' import ReactDOM from 'react-dom/client' import './index.css'; nt import { RouterProvider, createBrowserRouter, createRoutesFromElements, Route } from 'react-router-dom'; import Book from './book'; import Bookshop from './bookshop'; const router = createBrowserRouter( createRoutesFromElements( <Route> 👉 <Route path='/' element={<Book />}></Route> 👉 <Route path='bookshop' element={<Bookshop />}></Route> </Route> ) ) ReactDOM.createRoot(document.getElementById('root')).render( <React.StrictMode> <RouterProvider router={router} /> </React.StrictMode>, )
از مثال کد بالا، ما دو مؤلفه Book
و Bookshop
را وارد کردیم و آنها را از طریق تگ <a>
و مؤلفه Route
در مؤلفه ./src/main.jsx
پیوند دادیم.
⚠️ //book.jsx export default function Book() { return ( <> <main className="px-4"> <ul> <ol>77 Ways get to more customers By: <i>Ubuy</i></ol> <ol>Authenticity By: <i>Emanuel Rose</i> </ol> <ol> Change Your thinking change your life By: <i>Brian Tracy</i></ol> 👉 <a href="bookshop" className="text-blue-600 inline-block px-4 underline">see bookshop</a> {/* <a href="publisher/itemId" className="text-blue-600 underline">Publisher</a> */} </ul> </main> </> ) }
ویژگی href
مولفه bookshop
را به عنوان یک مسیر نسبی می پذیرد. پس با کلیک بر روی پیوند باید به مؤلفه bookshop
هدایت شوید.
⚠️ //bookshop.jsx export default function Bookshop() { return ( <div className="px-4"> <h1>list of book shops</h1> <ul> <li>Book Shop & Stationery</li> <li>Simon books</li> <li>Dynamic Book home</li> </ul> 👉 <a href="/" className="text-blue-600 inline-block px-4 underline">Names of Books</a> </div> ) }
href=”/”
در جزء کتابفروشی مسیر فهرست را مشخص می کند و باید شما را به اجزای اصلی هدایت کند.
برنامه شما باید در مرورگر شما به این شکل باشد - برای رفتن به مؤلفه کتابفروشی کلیک کنید.
از خروجی مرورگر بالا، متوجه خواهید شد که چگونه URL از نوار آدرس به روز می شود و یک جزء جدید ارائه می شود.
نوع مسیریابی، مسیریابی سمت مشتری نامیده می شود و تنها یک بار مسیر URL را با مسیر جدید به روز می کند.
در بخش بعدی توضیح خواهم داد که چگونه می توانید یک بخش خاص را به روز کنید و محتوا را به صورت پویا رندر کنید.
بخش های پویا
بخش پویا، همانطور که از نام آن پیداست، راهی برای ارائه یک جزء جدید (UI) با به روز رسانی یک بخش خاص در URL به نام پارامترها است. برای این کار از قلاب useParams از react-router-dom
استفاده می کنید.
این در شرایطی که محتوا باید از یک مؤلفه خاص یا API شخص ثالث به صورت پویا ارائه شود بسیار مفید است.
از جایی که در کد متوقف شدیم، به کامپوننت ./src/main.jsx
بروید. مسیر را ویرایش کنید و :itemId
به مسیری که در زیر نشان داده شده است اضافه کنید:
⚠️ //main.jsx <Route> <Route path='/' element={<Book />}></Route> <Route path='bookshop' element={<Bookshop />} /> 👉 <Route path='publisher/:itemId' element={<Publisher />} /> </Route>
توجه داشته باشید که :
در بخش URL :itemId
به معنای بخش پویا است.
سپس یک کامپوننت جدید به عنوان ./src/publisher.jsx
ایجاد کنید و کد زیر را اضافه کنید:
⚠️ //publisher.jsx import { useParams } from "react-router-dom" export default function Publisher() { const { itemId } = useParams(); return ( <> { itemId ? ( <div> <h1>Book publishing companies</h1> <ul> <ol>Penguin Random House</ol> <ol>Scholastic</ol> <ol>LPI Media</ol> </ul> </div> ) : ( <p>Page item is not present</p> ) } </> ) }
بیایید در مورد آنچه این کد انجام می دهد صحبت کنیم:
const { itemId } = useParams()
: در اینجا ما ساختارشکنی را اعمال می کنیم تا پارامترها را از URL در نوار آدرس دریافت کنیم. با این کار می توانیم محتوای برگشتی را رندر کنیم.
itemId?():
: در اینجا به صورت مشروط فهرستی از شرکت های کتابفروشی را ارائه می کنیم که پیوند کلیک شده با پارامترها مطابقت داشته باشد.
در مرحله بعد، در مؤلفه ./src/book
، publisher/itemId
همانطور که در تگ <a>
زیر نشان داده شده است قرار دهید:
⚠️ //book.jsx export default function Book() { return ( <> <main className="px-4"> <ul> <ol>77 Ways get to more customers By: <i>Ubuy</i></ol> <ol>Authenticity By: <i>Emanuel Rose</i> </ol> <ol> Change Your thinking change your life By: <i>Brian Tracy</i></ol> <a href="bookshop" className="text-blue-600 inline-block px-4 underline">see bookshop</a> 👉 <a href="publisher/itemId" className="text-blue-600 underline">Publisher</a> </ul> </main> </> ) }
برنامه شما باید در مرورگر شما به این شکل باشد:
به به روز رسانی در URL در نوار آدرس مرورگر توجه کنید.
بیایید به مثال دیگری نگاه کنیم.
در یک برنامه دنیای واقعی، بخشهای پویا عمدتاً برای نمایش پویا محتوا استفاده میشوند که بخش :itemId
با id
APIهای بازگشتی مطابقت داشته باشد.
بیایید ببینیم این چگونه کار می کند. ابتدا باید تصمیم بگیریم که داده های خود را از کجا واکشی کنیم. در این مورد، یک شی جاوا اسکریپت خارجی ./scr/books.js
ایجاد کنید و کد زیر را کپی و پیست کنید:
⚠️ //books.js export default [ { id: "1", title: "The Great Gatsby", author: "F. Scott Fitzgerald", year: "1925", description: "The Great Gatsby is a 1925 novel by American writer F. Scott Fitzgerald. Set in the Jazz Age on Long Island, near New York City, the novel depicts first-person narrator Nick Carraway's interactions with mysterious millionaire Jay Gatsby and Gatsby's obsession to reunite with his former lover, Daisy Buchanan." }, { id: "2", title: "Pride and Prejudice", author: "Jane Austen", year: "1813", description: "Pride and Prejudice is the second novel by English author Jane Austen, published in 1813. A novel of manners, it follows the character development of Elizabeth Bennet, the protagonist of the book" }, { id: "3", title: "To Kill a Mockingbird", author: "Harper Lee", year: "1960", description: "To Kill a Mockingbird is a novel by the American author Harper Lee. It was published in June 1960 and became instantly successful. In the United States" }, { id:"4", title: "Beloved", author: "Toni Morrison", year: "1987", description: "Beloved is a 1987 novel by American novelist Toni Morrison. Set in the period after the American Civil War, the novel tells the story of a dysfunctional family of formerly enslaved people whose Cincinnati home is haunted by a malevolent spirit" } ]
سپس یک کامپوننت جدید به نام ./src/FavBooks.jsx
ایجاد کنید و در کد زیر بنویسید:
⚠️ //FavBooks.js import { useParams } from 'react-router-dom'; import book from './book'; export default function FavBooks() { const {bookId} = useParams() 👉 const newFavBook = book.find((book) => book.id === bookId) if(!newFavBook){ return <p>{`This page doesn't contain fav Books`}</p> } return ( <> <main> {newFavBook && ( <> <main> <p>{`Title: ${newFavBook.title}`}</p> <p>{`By: ${newFavBook.author}`}</p> <p>{`Year: ${newFavBook.year}`}</p> <p>{`Description: ${newFavBook.description}`}</p> </main> </> )} </main> </> ) }
سپس به کامپوننت ./src/book.jsx
بروید و کد را به صورت زیر به روز کنید:
import { Link } from 'react-router-dom'; import books from './book.js'; export default function Books() { return ( <> <div className='m-4'> <p className="text-3xl">{`List of my favourite books`}</p> </div> <div className='m-4'> { books && books.map((book)=> ( <> <ul> <li> <Link to={`newbooks/${book.id}`} className='text-blue-600 underline'>{book.title}</Link> </li> </ul> </> )) } </div> </> ) }
سپس path
بخش پویا را در مولفه مسیر پیکربندی کنید:
import Book from '../src/books'; import Bookshop from './bookshop'; import Publisher from './publisher'; 👉 import FavBooks from './FavBooks'; const router = createBrowserRouter( createRoutesFromElements( <Route> <Route path='/' element={<Book />}></Route> <Route path='bookshop' element={<Bookshop />} /> <Route path='publisher/:itemId' element={<Publisher />} /> 👉 <Route path='newbooks/:bookId' element={<FavBooks />} /> </Route> ) )
برنامه شما باید در مرورگر شما به این شکل باشد:
از api در react" width="1366" height="408" loading="lazy">
از خروجی مرورگر، پارامترهای URL با بخش مسیر و مقادیر شناسه از شی books.js به روز می شوند.
سعی کنید روی هر یک از عناوین کلیک کنید و متوجه شوید که چگونه شناسه شی books.js در URL وجود دارد.
هنگامی که یک کاربر روی پیوند کلیک می کند، یک رابط کاربری جدید در یک صفحه جدید ارائه می کند. اما مواردی وجود دارد که ممکن است بخواهید محتوای API را در همان صفحه با موارد فهرست ارائه دهید، پس نیازی به باز کردن محتوا در صفحه جدید نیست. برای این کار باید مسیریابی تودرتو را پیاده سازی کنیم.
مسیریابی تودرتو
مسیریابی تودرتو این امکان را به شما می دهد تا مسیرها را برای نمایش اجزای جدید در همان صفحه برای ناوبری آسان و تعامل سریع عنصر ایجاد کنید. مسیرهای تودرتو باعث می شوند موارد فهرست شده به عنوان یک برگه عمل کنند. به محض کلیک روی هر برگه، محتوایی که با برگه مربوطه مطابقت دارد نمایش داده می شود.
حال بیایید ببینیم که چگونه برنامه کوچک خود را به یک مسیر تودرتو تبدیل کنیم.
برای رفتن به کامپوننت ./src/main
و ایجاد یک مسیر تودرتو به صورت زیر:
const router = createBrowserRouter( createRoutesFromElements( <Route> <Route path='/' element={<Book />} > 👉 <Route path='newbooks/:bookId' element={<FavBooks />} /> </Route> <Route path='bookshop' element={<Bookshop />} /> <Route path='publisher/:itemId' element={<Publisher />}> </Route> </Route> ) )
اساساً، ما مؤلفه FavBook
را به عنوان فرزند مستقیم آن در مؤلفه Book
قرار می دهیم، پس محتوا در زیر آن نمایش داده می شود.
بعد، یک تگ div ایجاد کنید و یک جزء خروجی را رندر کنید. این به ما میگوییم که مسیریاب واکنش نشان میدهد کجا مسیر جدید تودرتو را ارائه کند.
return ( <> <div className='m-4'> <p className="text-3xl">{`List of my favourite books`}</p> </div> 👉 <section className='flex'> <div className='m-4'> { books && books.map((book)=> ( <> <ul> <li> <Link to={`newbooks/${book.id}`} className='text-blue-600 underline'>{book.title}</Link> </li> </ul> </> )) } </div> <div className='w-[70%]'> 👉 <Outlet /> </div> </section> </> )
توجه داشته باشید که برای رندر کردن مؤلفه FavBook
تودرتو در کنار هم، هر دو تگ خروجی و فهرست کتاب در یک تگ بخش تودرتو هستند و یک سبک نمایش انعطاف پذیر اعمال می شود.
کد شما باید در مرورگر شما به شکل زیر باشد:
از خروجی مرورگر، میتوانید ببینید که هر آیتم فهرستشده بهعنوان یک برگه عمل میکند و با کلیک کردن روی آنها محتوای API نمایش داده میشود.
شما یاد گرفته اید که چگونه یک بخش پویا ایجاد کنید. در بخش بعدی، پروژه ای خواهیم ساخت تا به تقویت بیشتر آموخته هایمان کمک کند.
پروژه: ساخت یک گالری هنری
در این پروژه قصد داریم یک اپلیکیشن گالری هنری بسازیم که حاوی فهرست ی از مجسمه ها و هنرهای کشورهای مختلف است. این به شما کمک می کند تا مفاهیمی را که قبلاً یاد گرفته اید تقویت کنید.
ما قصد داریم ویژگی های زیر را پیاده سازی کنیم:
مسیریابی سمت مشتری
لینک های فعال
بخش های پویا
مسیرهای تو در تو
در زیر یک نمای کلی از این که پروژه چگونه خواهد بود را نشان می دهد.
تحلیل اجمالی پروژه
در اینجا یک پیش نمایش کامل از پروژه ما پس از اتمام است. می توانید کد منبع را در 👉 GitHub از اینجا دانلود کنید.
ساختار پوشه
ساختار پوشه پروژه باید به این صورت باشد:
📂src 📂apis ├──data.js 📂components ├──AsideBar.jsx ├──Content.jsx ├──Navbar.jsx 📂pages ├──home.jsx ├──index.css ├──main.jsx ├──index.html
نحوه تنظیم صفحه اصلی
برای تنظیم صفحه اصلی، یک کامپوننت اصلی ./src/pages/home.jsx
ایجاد کنید و کد زیر را اضافه کنید:
├──home.jsx export default function Home() { return ( <> <main className=""> <section> <p className="text-orange-600">Hello World</p> </section> </main> </> ) }
سپس به کامپوننت main.jsx
بروید. اگر هنوز یکی را ندارید، آن را به صورت ./src/main.jsx.
سپس مسیر را به صورت زیر پیکربندی کنید:
├──main.jsx import React from 'react' import ReactDOM from 'react-dom/client' import './index.css'; import { RouterProvider, createBrowserRouter, createRoutesFromElements, Route } from 'react-router-dom'; import Home from './pages/home'; const router = createBrowserRouter( createRoutesFromElements( <Route path='/' element={<Home />}> </Route> ) ) ReactDOM.createRoot(document.getElementById('root')).render( <React.StrictMode> <RouterProvider router={router} /> </React.StrictMode>, )
در مرحله بعد، npm run dev
تایپ کنید تا برنامه شما راه اندازی شود.
برنامه شما باید در مرورگر شما به این شکل باشد:
نحوه ایجاد و استایل نوار ناوبری
اکنون که مؤلفه خانه و مسیر را راهاندازی کردهایم، بیایید مؤلفه نوار ناوبری را ایجاد کنیم که مؤلفه برتر در برنامه ما است.
یک کامپوننت ./src/components/navbar.jsx
ایجاد کنید و کد زیر را اضافه کنید:
├──navbar.jsx import { Activity, Search } from "react-feather"; export default function Navbar() { return ( <> <main className=""> <header> <nav className="flex justify-between bg-slate-200 rounded-3xl py-2"> {/* logo */} <div className=""> <Activity className="inline-block ml-10 mr-2 text-orange-500" /> <p className="inline-block text-xl">{`Arts & Culture`}</p> </div> {/* Navlinks */} <div className="bg-white rounded-3xl py-1 px-2 mr-5"> <Search className="inline-block mr-1 text-slate-500"/> <input type="search" id="site-search" name="q" placeholder="Search anything" className="bg-transparent outline-none text-slate-800"/> </div> </nav> </header> </main> </> ) }
از کد بالا، نوار ناوبری بین لوگو و نوار جستجو تقسیم شده است.
لوگو: ما نمادهای Activity را به عنوان یک مؤلفه از نمادهای پر وارد می کنیم و از کلاس های Tailwind CSS برای استایل دادن به آن استفاده می کنیم. آیکون روی inline-block
تنظیم شده است تا بتوانیم به آن فاصله اعمال کنیم. ml-10
و mr-2
را اعمال می کنیم که حاشیه سمت چپ 2.5rem
و سمت راست 0.5rem
با رنگ نارنجی ( text-orange-500
) است.
جستجو : برای نوار جستجو، ما همچنین آن را از نمادهای پر به عنوان یک مؤلفه وارد کردیم و استایل زیر را اعمال کردیم: inline-block mr-1 text-slate-500
. اگر در درک کلاسهای Tailwind CSS مشکل دارید، میتوانید اطلاعات بیشتری در مورد آنها از اسناد اینجا بخوانید.
برای قرار دادن لوگو و نوار جستجو در کنار هم، هدر والد را طوری تنظیم میکنیم که منعطف و توجیه محتوای فاصله بین را نمایش دهد تا فاصله بین لوگو و نوار جستجو اعمال شود.
سپس نوار ناوبری را به صورت زیر به مسیر اضافه کنید:
├──main.jsx import React from 'react' import ReactDOM from 'react-dom/client' import './index.css' import { RouterProvider, createBrowserRouter, createRoutesFromElements, Route } from "react-router-dom" 👉 import Navbar from './components/Navbar' import Home from './pages/home' const router = createBrowserRouter( createRoutesFromElements( <Route path='/' element={<Home />}> 👉 <Route path='/' element={<Navbar />} /> </Route> ) ) ReactDOM.createRoot(document.getElementById('root')).render( <React.StrictMode> <RouterProvider router={router} /> </React.StrictMode>, )
از کد بالا، کامپوننت Navbar در داخل اجزای Home قرار گرفته است. این بدان معناست که ما باید از یک کامپوننت Outlet برای رندر مولفه Navbar استفاده کنیم.
در مرحله بعد، به کامپوننت ./src/page/home
بروید، وارد کنید، و همانطور که در زیر نشان داده شده است <p>
را با مولفه Outlet جایگزین کنید:
├──home.jsx 👉 import { Outlet } from "react-router-dom"; export default function Home() { return ( <> <main className=""> <section> 👉 <Outlet /> </section> </main> </> ) }
برنامه شما باید در مرورگر شما به شکل زیر باشد:
نحوه ایجاد AsideBar
AsideBar
یکی از مهم ترین اجزای برنامه ما است. این جایی است که نام فرهنگ ها نمایش داده می شود. این مؤلفه بهعنوان یک برگه عمل میکند و زمانی که کاربر روی آن کلیک میکند، جزئیات بیشتری در مورد فرهنگی که روی آن کلیک شده است را نشان میدهد.
یک کامپوننت جدید به عنوان ./src/components/AsideBar.jsx
ایجاد کنید و در کد زیر بنویسید:
├──AsideBar.jsx import { NavLink } from "react-router-dom" import data from "../apis/data" export default function AsideBar() { const activeStyle = ({isActive}) => { return { backgroundColor : isActive ? "rgb(154 52 18)" : "", color : isActive ? "rgb(255 247 237)" : "", } } return ( <> <main className="w-[100%] mt-[2em]"> <section className="w-[100%]"> <aside className="w-[fit-content] bg-slate-200 rounded-xl"> { data.map((data)=>( <ul key={data.id}> <li className=""> <NavLink className="w-[100%] py-3 px-2 inline-block text-slate-800 hover:bg-orange-200 transition-all whitespace-nowrap border-y-4 " to={`content/${data.id}`} style={activeStyle}> {data.type} </NavLink> </li> </ul> )) } </aside> </section> </main> </> ) }
از مثال کد بالا، کد ما به دو بخش تقسیم شده است: data
و جزء NavLink
.
دادهها: ما دادهها را از ./src/apis/data.js
وارد کردیم و هر آرایه از اشیاء را نگاشت میکنیم و data.type
را به عنوان نام AsideBar
برمیگردانیم.
NavLink : دادههای بازگردانده شده از data.js
مستقیماً در مؤلفه NavLink
ارائه میشوند. مولفه NavLink
دارای دو پایه است، style
و to
props مشخص شده است. این style
شیء activeStyle
را دریافت کرد که نشان میدهد وقتی NavLink
فعال است چه سبکی باید اعمال شود. to
prop to={
content/${data.id} }
data.id
را بهعنوان قطعهای ارسال میکنیم تا با path
مؤلفههای محتوا مطابقت داشته باشد ( اطلاعات بیشتر در این مورد در بخش بعدی ). این کار باعث میشود وقتی روی NavLink
کلیک میشود، محتوا بهصورت پویا نمایش داده شود.
در مرحله بعد، به کامپوننت home بروید و AsideBar
را همانطور که در زیر نشان داده شده است رندر کنید:
├──home.jsx import { Outlet } from "react-router-dom"; 👉 import AsideBar from "../components/AsideBar"; export default function Home() { return ( <> 👉 <main className="w-[80%] mt-[2em] mx-auto"> <section> <Outlet /> </section> <section> <aside> 👉 <AsideBar /> </aside> </section> </main> </> ) }
برنامه شما باید در مرورگر شما به این شکل باشد:
از تعامل با Asidebar
، ممکن است متوجه شده باشید که هر بار که روی پیوندها کلیک می کنید، صفحه شکسته می شود. دلیلش این است که جزء محتوا هنوز تعریف نشده است. پس بیایید آن را ایجاد کنیم.
نحوه ایجاد کامپوننت محتوا
مؤلفه محتوا محتوایی را ارائه می دهد که به پیوند خاصی که روی آن کلیک شده است مربوط می شود.
یک کامپوننت جدید به نام ./src/components/Content.jsx
ایجاد کنید و کد زیر را اضافه کنید:
├──Content.jsx import { Link, useParams } from "react-router-dom"; import data from "../apis/data.js"; import { WifiOff } from "react-feather"; export default function Content() { const {contentId} = useParams() const newData = data.find((data)=> data.id.toString() === contentId) if(!contentId){ return ( <main className="translate-x-44 translate-y-44"> <div className=""> <WifiOff className="text-slate-400 text-center translate-x-48"/> <p className="text-slate-400">{`Content can't be accessed! click the left nav to reload`}</p> </div> </main> ) } return ( <> <main className="w-[80%] mx-auto mt-8"> <section > { newData && ( <> {/* Image Over */} <aside className="h-[6em] w-[100%]"> <div className="h-[100%] w-[100%]"> <img src={newData.imgHeaders} alt="" className="h-[100%] w-[100%] object-cover rounded-xl"/> </div> </aside> {/* Details */} <section className="flex gap-6"> <aside className="w-[50%]"> <div> <p className="bg-orange-500 w-[fit-content] rounded-xl mt-4 py-1 px-2 font-bold">{newData.catagories}</p> <h1 className="font-light text-4xl my-7">{newData.type}</h1> <p className="font-bold mb-4 text-2xl">{newData.region}</p> </div> <div> <p className="font-light">{newData.history}</p> </div> <div className="mt-4"> <span>{`Learn more from`}</span> <Link to={newData.britannicaLink} target="_blank" className="text-orange-500 py-2 px-2 rounded-md inline mt-4 hover:underline hover:text-black">britannica</Link> </div> </aside> {/* Image Cover */} <aside className="w-[50%]"> <div> <img src={newData.imgCover} alt="" className="rounded-3xl mt-10"/> </div> </aside> </section> </> ) } </section> </main> </> ) }
کد بالا کار زیر را انجام می دهد:
useParams : ما از قلاب useParams() برای برگرداندن جفتهای کلید و مقدار content/:contentId
مشخص شده در مسیر استفاده میکنیم.
newData : با استفاده از روش آرایه find() اولین عنصر آرایه شی در صورت درست بودن شرط برگردانده می شود، در غیر این صورت undefined
برمی گرداند.
if(!contentId) : در اینجا، ما در حال تحلیل هستیم که آیا contentId
مطابقت ندارد یا هنوز رندر نشده است - سپس عنصر ارائه شده در تابع باید اجرا شود. این برای تحلیل خطاها و در شرایطی که محتوا در دسترس نیست بسیار مفید است.
newData && : در اینجا ما از طریق شی داده بازگشتی نقشه برداری می کنیم و محتوای API را به محض بارگیری محتوا ارائه می دهیم. هر ویژگی شی به یک عنصر تجزیه می شود تا به عنوان محتوا ارائه شود.
در مرحله بعد، به کامپوننت home بروید و کامپوننت محتوا را همانطور که در زیر نشان داده شده است رندر کنید.
├──home.jsx import { Outlet } from "react-router-dom"; import AsideBar from "../components/AsideBar"; 👉 import Content from "../components/Content"; export default function Home() { return ( <> <main className="w-[80%] mt-[2em] mx-auto"> <section> <Outlet /> </section> <section className="flex"> <aside> <AsideBar /> </aside> <aside> 👉 <Content /> </aside> </section> </main> </> ) }
سپس مسیر را به یک بخش پویا پیکربندی کنید:
├──home.jsx import Home from './pages/home'; import Navbar from './components/navbar'; 👉 import Content from './components/Content'; const router = createBrowserRouter( createRoutesFromElements( <Route path='/' element={<Home />}> <Route path='/' element={<Navbar />}> 👉 <Route path='content/:contentId' element={<Content />} /> </Route> </Route> ) ) ReactDOM.createRoot(document.getElementById('root')).render( <React.StrictMode> <RouterProvider router={router} /> </React.StrictMode>, )
برنامه شما باید در مرورگر شما دقیقاً شبیه این باشد:
با کلیک بر روی Asidebar
، محتوا از API بارگیری می شود و در همان صفحه ای که Asidebar
قرار دارد، نمایش داده می شود.
خلاصه
در این آموزش با Dynamic Segments در React Router آشنا شدیم. ما در مورد اینکه Dynamic Router چیست و چه تفاوتی با مسیریابی استاتیک دارد صحبت کردیم. همچنین یاد گرفتید که چگونه از قلاب useParams
برای فعال کردن بخش های پویا و همچنین نحوه تنظیم مسیر خود هنگام دریافت داده از یک API استفاده کنید.
سپس یک پروژه جدید ساختیم که وقتی کاربر روی نوار کناری کلیک میکند، محتوای جدید را به صورت پویا در همان صفحه نمایش میدهد.
شما می توانید این پروژه را جلوتر ببرید و با اجرای ویژگی های بیشتر آن را متعلق به خود کنید.
ارسال نظر