react notes (font $ Rout)

فونت : برای استفاده از بوت استراپ داخل پروژه به راحتی انرا توسط npm نصب و ازمستندات اموزش انرا پیاده سازی میکنیم . برای استفاده از font awesome نیز به راحتیم میتوان هم از npm دانلود کرد و هم از سایت cdn استفاده کرد و cdn مخصوص اونو اضافه کرد.بعد از نصب بوت استراپ جهت استفاده از آن می توان آن را در فایل Index.js ایمپورت کرد که از مسیر موجود در node.module میتوان نسخه min انرا Import کرد و در نهایت هر جای برنامه می توان از کلاس های بوت استراپ استفاده کرد.همچنین راه دیگه برای استفاده از بوت استراپ اینه که بریم تو پوشه node.module و بیایم دو تا فایل botstrap.min.css and bootstrap.min.js را در پوشه public قرار میدیم و اینبار در فایل html بهش Link میدیم و این کار برای سبک تر شدن برنامه می باشد. برای font awesomme هم دقیقا به همین روش می توان استفاده کرد ، فقط تنها تفاوتش اینه که باید پوشه font هم به طور کامل وارد پروژه کنیم و در نهایت میتوان آنرا حذف کرد و برای استفاده از فونت هم کافیه از طریق classname کلاس مخصوصشو مثلا به یه span بدیم. جهت اضافه کردن فونت مد نظر خودمون ، اول میایم و اون فونت رو دانلود میکنیم ، با پسوند tft و بعد برای اینکه در همه مرورگرها مشکل نخوریم میایم و در سایت transfonter فونت مد نظرمون رو انتخواب میکنیم و تمامی فرمت هاشو به عنوان خروجی میگیریم و بعد فونت هارو میایم داخل فولدر مد نظرمون داخل پروژمون میزاریم مثلا داخل پوش public/font و همچنین فایل css مد نظر که داخل پوشه فونت هست را نیز میایم داخل پروژه مثلا در مسیر public/css میزاریم و سپس در فایل css فونت مسیر ها را درست میکنیم و در نهایت در فایلhtml پروژه به css لینک میدیم و در این مرحله هر جای کد که بخوایم استایل مربوط به فونتو میدیم : <p style={{'vazir'}} >hello</p> همچنین میتونیم این فونتو در جایی از پروژه بزاریم که برای همه اعمال شود مثلا در Index.cssنکات جلسه 52 : fragment: در jsx همان طور که میدانید در صورتی که بخواهیم از چند المنت مثلا <p> کنار هم استفاده کنیم و در یک کامپوننت آنهارا return دهیم ، حتما باید یک المنت والد مثل <div> داشته باشند ، اما در جایی که ما بخواهیم از هیچ المنت والدی استفاده نکنیم ، در این هنگام از fragment ها استفاده می شود چون فراگمنتها هیچ node را به dom آضافه نمی کند و به این صورت نوشته میشود : <fragment></fragment> or <></> هر دوی این ها فراگمنت هستند و فرقی در استفاده از انها نیستنکات جلسه 56: نحوه import بهتر:فرض کنید داخل یک پوشه با نام contact تعدادی کامپوننت داریم مثلا با نام های addContact,editContact,... حال میخواهیم تمامی این کامپوننت هارو بیایم و داخل یک کامپوننت دیگه مثلا App ایمپورت کنیم ، روش معمول به این صورت هست که تک تک اینارو بیایم و ایمپورت کنیم import addContact from './component/contact/addContact' ; اما روش بهتری نیز وجود دارد که میایم مثلا داخل همون پوشه component و یک فایل با نام index.js میسازیم و بعدش همه این کامپوننت هارو داخل اون فایل export میگیریم برای مثال : export {default as addContact} from './component'; و در نهایت داخل کامپوننت App خیلی راحت تو یه خط هر چند تاشونو که بخوایم Import میکنیم:import {addContact,...} from './component';روت Rout : ما در ریکت نمیتوانیم وقتی درون برنامه از یک صفحه به یک صفحه دیگه میخوایم بریم از تگ <a> استفاده کنیم ، به علت اینکه در ریکت ما درواقع به صورت spa کار میکنیم و یک صفحه جدیدو به صورت یک کامپوننت جدید در اوردیمو استفاده میکنیم . پس برای استفاده از روت در ریکت از یک کتابخانه با نام react-router-dom استفاده میکنیم.جهت نصب هم کافی است از طریق npm install انرا نصب کنیم .سپس داخل فایل index.js شروع میکنیم و از این کتابخانه موارد دلخواه را ایمپورت میکنیم که اولین مورد browserRoture هست که در این فایل بالاترین جای ممکن قرارش میدیم تا کل اپلیکیشن ما دسترسی به مرورگرو داشته باشن .import { BrowserRouter } from &quotreact-router-dom&quot.....const root = ReactDOM.createRoot(document.getElementById(&quotroot&quot));root.render( <React.StrictMode> <BrowserRouter> <App /> </BrowserRouter> </React.StrictMode>,); حال در صورتی که بخواهیم در یکی از صفحاتمون به یک صفحه دیگمون لینک بدیم( بین کامپوننت ها جابه جا شیم و صفحه قرار نیست reload شه چون ما spa هستیم) برای اینکار باید ابتدا از داخل react-roture-dom یک Link را ایمپورت می کنیم سپس از طریق این سینتکس لینک را در صفحه مد نظر قرار مید هیم : <Link to={/destinationPath}> نام مدنظر </Link> اما در نظر داشته باشین که وقتی ما از link استفاده می کنیم در نهایت به تگ <a> تبدیل میشوند ، اما این Link به ما اجازه دسترسی ایمن از تگ a را میدهد و باعث میشه لینک به صورت داخل اپلیکیشنی باشد.اشنایی با Routs and Rout : جهت مسیر دهی مناسب در پروژه باید از این دو استفاده کرد و مسیر ها را مشخص کرد که در اینجا App / About / Books کامپوننت های ما هستند و ما این مسیرهارو در فایل Index.js تعریف کردیم : <BrowserRouter> <Routes> <Route path=&quot/&quot element={<App />}> // مسیر روت <Route path=&quot/about&quot element={<About />} /> <Route path=&quot/books&quot element={<Books />} /> </Route> </Routes> </BrowserRouter> حال نکته این که خیلی مهم است اینه که، ما در صورتی که بخوایم مسیرهامون به هم ربط نداشته باشه ، <Rout > ها زیر هم و هم ردیف هم قرار میگیرند اما در صورتی که بخوایم برای مثال داخل خود App باشیم و اون جا وقتی با استفاده از Link به مثلا Books بریم و Books هم داخل خود App نشون داده بشه مثل بالا به صورت فرزند مسیر App تعریفشون میکنیم و در کامپوننت App هم محلی که میخوایم فرزنداش نمایش داده شن از <outlet> استفاده میکنیم :import { Link, Outlet } from &quotreact-router-dom&quot ...... const App = () => { return ( <div className=&quotApp&quot> <h1>کتابخانه من</h1> {/*About - Books*/} <nav style={{ borderBottom: &quotsolid 1px&quot, paddingBottom: &quot1rem&quot }}> <Link to=&quot/books&quot>کتاب ها</Link>{&quot &quot}<Link to=&quot/about&quot>درباره ما</Link> </nav> <Outlet /> // اینجا محل قرار گیری فرزندهاش هستند </div> );}; هر جایی که در ریکت ما روی هر چیزی حلقه میزنیم حتما از key نیز استفاده باید کرد ، چون ریکت بفهمه با کدوم یک از اعضا دره کار میکنه . حال در نظر بگیریم حالتی که برای مثال ما لیستی از کتاب ها دریم که نمایششون میدیم مثل زیر و میخوایم روی هر کتابی که کلیک میکنیم یه لینک بدیم و مثلا بریم داخل جذییات کتاب ، خب کدهای زیر نحوه استفاده از آی دی در لینکو نشون میدن : {books.map((book) => ( <Link style={{ display: &quotblock&quot }} to={`/books/${book.number}`} key={book.number} > {book.name} </Link> ))}و داخل مسیر دهی هم به این صورت میشه :<Route path="/books/:bookId" element={<Book />} />لازم به ذکر است حال وقتی روی این لینک میزنیم در URL هم آی دی Book نمایش داده میشود و ما برای اینکه در صفحه Book بخواهیم کتاب مد نظر را نمایش دهیم باید آی دی کتاب را از URL دریافت کنیم که برای اینکار ابتدا Use-params را از react-router-dom ایمپورت میکنیم و با چند خط زیر اینکارو انجام میدیم (لازم به ذکر است که useparams یک object برمیگردونه که داخلش هم به صورت string هست:Import { useParams } from &quotreact-router-dom&quot ... const Book = () => { const params = useParams(); const book = getBook(parseInt(params.bookId));// چون رشته است باید تبدیل شه return ( <main style={{ padding: &quot1rem&quot }}> <h2>قیمت کل : {`${book.amount} تومان`}</h2>// book یک ابجت است <p> {book.name} </p> <p> تاریخ انتشار : {book.due} </p> <p> <button>حذف کتاب</button> </p> </main> );}; چند نکته هم در اخر مهم می باشد وقتی در مسیر دهی ، یک المنت فرزند المنت دیگری می شود ، دیگه نیاز نیست در قسمت مربوط به path ادرس را کامل بزنیم و ادرس والد از والد میگیره و همچنین اگه در فرزندی به جای استفاده از path از index استفاده کنیم به این معنی است که مسیرش دقیقا مسیر والد می باشد مثل کد زیر : <Route path=&quot/books&quot element={<Books />}> <Route index // مسیرش میشه دقیقا مسیر اولیه والد element={ <main style={{ padding: &quot1rem&quot }}> <p>کتاب مورد نظر خود را انتخاب نمائید</p> </main> } /> <Route path=&quot:bookId&quot element={<Book />} />// در مسیر دیگه لازم نیست مسیر کامل داده بشه </Route>نحوه پیاده سازی مسیر Not Found : برای وقتی است که کاربر هر Url دیگه ای غیر از مواردی که ما تغریف کردیمو وارد کرد ، اینو ببینه که برای این کار کافی است یک <Rout> جدید ، خارج در سایر روت ها قرار میدیم و در قسمت path = {*} قرار میدهیم که به این معنی است که هرچیزی وارد کرد کاربر به این آدرس برود البته به غیر از مسیر هایی که خودمون تعریف کردیم و خیلی راحت یک کامپوننت هم براش میسازیم در قسمت element قرار میدیم. نکته اخر اینه که الان فقط یه مشکل میمونه ، اونم وقتیه که کاربر مثلا میاد یه کتاب رو میخواد از روی آی دیش وارد صفحه جذییاتش بشه ، اما در صورتی که اون آی دی نباشه با ارور مواجه میشیم که فعلا میشه از رندر شرطی استفاده کرد و اینو هندل کرد که مثلا اگه کتابی با آی دی مد نظر پیدا شند چه اتفاقی بیفته.پیاده سازی Nav Link : در حالتی که برای مثال شما لیستی از کتاب های ، کاربران یا هر لیستی داشته باشین وبخواین هندل کنید که وقتی کاربر روی یکی از اونها کلیک کرد به حالت active دربیاد ، در این حالت از navlink ها می توان استفاده کرد.نحوه استفاده کردنش دقیقا مثل Link میمونه و در پایین نحوه پیاده سازیشو اوردم : <NavLink style={({ isActive }) => { // در اینجا داخل پرانتزو خود نو لینک میده بهمون return { display: &quotblock&quot, margin: &quot1rem 0&quot, color: isActive ? &quotred&quot : &quot&quot, }; }} to={`/books/${book.number}`} key={book.number} > {book.name} </NavLink>آشنایی با هوک های useSearchParams و useLocation : هوک useSearchParams دقیقا مثل state داخل ریکت عمل میکند ولی به جای اینکه داده را داخل حافظه سیستم ذخیره کند ، در آدرس مرورگر ذخیره میکند . در اینجا فرض کنیم که میخواهیم از طریق این هوک روی لیستی از کتابها سرچ لحظه ای انجام دهیم ، نحوه این کار در پایین اورده شده است(چیزی که در URl مشاهد میکنید به این صورت است که بعد از مسیر مد نظر ):?filter=مقداری که در اینپوت تایپ میشودimport { NavLink, Outlet, useLocation, useSearchParams,} from &quotreact-router-dom&quotconst Books = () => { const [searchParams, setSearchParams] = useSearchParams(); // دقیقا مثل استیت و با اسامی دلخواه.............. return ( <div style={{ display: &quotflex&quot }}> <nav style={{ borderLeft: &quotsolid 1px&quot, padding: &quot1rem&quot }}> // داخل اینپوت زیر عملیات سرچ انجام می شود <input type=&quottext&quot value={searchParams.get(&quotfilter&quot) || &quot&quot} // فیلتر یک نام دلخواه است که به عنوان کلید از یو ار ال دریافت میشود ={(event) => { // از این طریق مقدار این هوک پر میشود let filter = event.target.value; if (filter) { setSearchParams({ filter }); } else { setSearchParams({}); } }} placeholder=&quotجستجوی کتاب&quot /> {books.filter((book) => { // جهت نمایش کتاب هایی که فیلتر شده است let filter = searchParams.get(&quotfilter&quot); if (!filter) return true; let name = book.name.toLowerCase(); return name.startsWith(filter.toLowerCase()); }) .map((book) => ( <NavLink style={({ isActive }) => { return { display: &quotblock&quot, margin: &quot1rem 0&quot, color: isActive ? &quotred&quot : &quot&quot, }; }} to={`/books/${book.number}`} key={book.number} > {book.name} </NavLink> ))} </nav> <Outlet /> </div> );};export default Books;اما در ارتباط با هوک useLocation وظیفه در اختیار دادن اطلاعاتی از ادرس مدنظر مثل مقدار سرچ برابر چیست ، داخل کدام ادرسیم ، مقدار کلید و state چیست و ... . برای استفاده از آن کافی است آنرا از react-router-dom ایمپورت کنیم . سپس از این سینتکس ()const location = useLocation در دسترس خواهد بود و در مثال بالا ، استفاده که به کار ما میاد اینه که با توجه به این که ما صفحه Books و Book را در داخل هم قرار داده ایم به این صورت که لیست کتاب ها در سمت راست باشند و با انتخواب هر کتاب مقابل این لیست جذییات مربوط به کتاب باز شود و از طریق NavLink به صفحه Book اتصال میابیم به جهت اینکه مقدار سرچ شده را نیز داخل URL قرار دهیم تا وقتی که روی اون کتاب کلیک کردیم نیز مقدار سرچ شده هم ارسال شود و لیست کتاب ها به حالت اولیه برنگردد ، جهت دریافت مقدار سرچ در اینجا از این هوک استفاده میکنیم که فقط کافی است در قسمت NavLink به این صورت عمل کنیم : to={`/books/${book.number}${location.search}`} لازم به ذکر است location نیز یک ابجکت را برمیگرداند و جهت استفاده از داخل ان به این شکل عمل می شود.استفاده از هوک useNavigate : برای موقعی استفاده میشه که مثلا بخوایم تو یه صفحه جذییات کتاب ، بخوایم اون کتابو حذف کنیم که خب یک btton پس می سازیم که با کلیک روش اون کتاب حذف شه و اینجا با استفاده از این هوک بعد از حذف یه مسیر جدید میدیم که کاربر بره اونجا ، مثلا بره به صفحه نمایش همه کتاب ها ، نمونه کد در زیر اومده : <button ={() => { deleteBook(book.number); navigate(&quot/books&quot + location.search); // اینجا چون سرچ داریم از لوکیشن هم استفاده شده }} > delete </button>