ICSI301 Төсөл 4: React хуудас үүсгэх нь

Тохиргоо

Та өөрийн систем дээрээ Node.js болон npm модуль менежерийг суулгасан байх ёстой. Хэрэв үгүй бол, суулгах зааврыг дагаж одоо суулгаарай.

project4 нэрээр хавтас үүсгэж энэ файлыг дотор нь задалж хуулаарай. Энэ zip файл энэ даалгаварт ашиглах гарааны файлуудыг агуулж байгаа.

Энэ даалгаварт Node.js-ийн 20.19, 22.13 эсвэл 24-өөс дээш хувилбар шаардлагатай. Мөн хэд хэдэн node модуль (жишээ нь, Vite, ESLint) хэрэгтэй. Vite нь React веб аппыг хөгжүүлэх үед JSX файлуудыг ЖаваСкрипт болгон хөрвүүлж веб хөтчид өгч үйлчилдэг хөгжүүлэлтийн сервер, мөн веб аппыг босгох (build) багаж юм. Эдгээр модулийг project4 хавтас дотроос дараах командыг ажиллуулж суулгана:

npm install
Энэ команд шаардлагатай node модулиудыг node_modules гэсэн дэд хавтас дотор татаж авна.

Төслийн бүтэц нь npm create vite@latest -- --template react командаар үүсгэдэг Vite-ийн стандарт бүтэц дээр суурилсан. Аппын бүх эх код src хавтаст, HTML хуудсууд төслийн үндсэн хавтаст байрлана.

Бид npm командыг янз бүрийн багажууд татаж авахад хэрэглэдэг. package.json файлын "scripts" шинжид харагдаж байгаа шиг дараах командуудыг ажиллуулах боломжтой:

  • npm run dev - Vite хөгжүүлэлтийн серверийг асаана. Та файлаа өөрчилж хадгалах бүрт веб хөтөч дээрх хуудас автоматаар шинэчлэгдэнэ. Хөгжүүлэлтийн явцад үүнийг үргэлж ажиллуулж байна.
  • npm run build - vite.config.js файлд байгаа тохиргоогоор аппын бүх JSX файлуудыг багцалж dist хавтас дотор ЖаваСкрипт багц (bundle) файлууд үүсгэнэ. npm run preview командаар үүсгэсэн багцыг веб хөтөч дээр шалгаж болно. Энэ даалгаварт заавал биш.
  • npm run lint - ESLint багажийг төслийн бүх ЖаваСкрипт файлд ажиллуулна. Даалгавраар илгээх таны код чинь ESLint програмыг ямар нэг санамжгүйгээр (warnings) давсан байх ёстой.

Бүх даалгаварыг гүйцэтгэсэн кодууд project4 хавтас дотор байх ёстой.

Энэ төсөлд веб аппыг хөгжүүлэхэд түгээмэл болсон React санг ашиглана. Энэ төслийн зорилго бол таныг React-д хурдан суралцаж ICSI301 хичээлийн дараагийн төслүүдээр хийх веб аппыг хөгжүүлэхэд бэлэн болгох юм.

Хөгжүүлэлтийн серверийг project4 хавтас дотроос дараах командаар асаана:

npm run dev

project4 хавтас доторх бүх хуудсуудад http://localhost:5173 гэж эхлэх URL хаягаар хандана. http://localhost:5173 линк дээр дарж өөрийнхөө серверийг ажиллаж байгаа эсэхийг шалгаж болно. Энэ нь index.html файлыг таны веб хөтчид өгөх болно.

Энэ ганц команд веб сервер болон JSX-ийг хөрвүүлэх багажийг хамт ажиллуулдаг тул өөр команд ажиллуулах шаардлагагүй. JSX-ийн синтакс алдааг Vite командын мөрөнд болон веб хөтөч дээр шууд харуулна. Серверийг зогсоохдоо командын мөрөн дээр Ctrl+C дарна.

Эхлэл

Энэ төслөөр лекцээр үзсэн model, view, controller (модель, харагдац, удирдлага) үлгэр загварыг ашиглах болно. Энэ загварын дагуу кодыг зохион байгуулах олон янзын арга бий. Бид нэгийг нь жишээ болгож React-ийн зарим үндсэн онцлог, мөн файл систем дэх байршлын зохиомж, модуль загвар зэргийг харуулж байна. Энэ үлгэр загварыг та дараагийн төслөөр хэрэгжүүлж яваарай.

Та энэ жишээг веб хөтөч дээрээ http://localhost:5173/getting-started.html URL хаягаар эхлүүлэн харж болно. Энэ хуудас нь React-ийг бодитоор ажиллуулж буй жишээ юм. getting-started.html хуудсанд байгаа HTML нь React аппыг зурж харуулахад зориулж нэг <div> элементийг , аппын JSX файлыг холбож ажиллуулахад хэрэгтэй нэг script элементийг агуулж байгаа:

<script type="module" src="/src/gettingStarted.jsx"></script>
Vite нь src/gettingStarted.jsx файлыг веб хөтчид өгөхийн өмнө ЖаваСкрипт болгон хөрвүүлдэг тул тусад нь багц үүсгэх шаардлагагүй. src/gettingStarted.jsx бол нэг JSX програм бөгөөд createRoot функцээр getting-started.html дотор байгаа нөгөө <div> дээр React-ийн root үүсгэж, Example нэртэй компонентийг <StrictMode> дотор рендерлэж харуулна.

Дахин ашиглах компонентийг хөгжүүлэхэд React компонент болон түүнд холбоотой CSS файлуудыг src/components дэд хавтас дотор зохион байгуулсан. Жишээ нь, Example компонентийг src/components/Example/{Example.jsx,Example.css} файлуудад хөгжүүлсэн.

Та getting-started.html хуудсыг дуудахад хэрэг болж байгаа файлуудыг (getting-started.html, src/gettingStarted.jsx, src/components/Example/Example.jsx) үзээрэй. Эдгээр нь React веб аппыг ажиллуулахад шаардлагатай ЖаваСкрипт болон JSX командуудыг тайлбар комментын хамт харуулж байгаа. Та хичээлээр босгох бусад компонентоо хөгжүүлэхэд энэ үлгэр загварыг нэрийн зохицолтойгоор (naming conventions) хэрэглэх ёстой.

Моделийн өгөгдлийг ихэвчлэн веб серверээс авдаг. Веб сервер нь өгөгдлийн сангаас авдаг. Энэ төслөөр өгөгдлийн санг тохируулж хэрэглэхээс зайлсхийж модель өгөгдлийг src/modelData хавтаст ЖаваСкрипт модуль (ES module) болгон бэлдэж өгсөн байгаа. Модель нь icsi301models нэртэй объектын шинжүүдэд хадгалагдана. React компонент дотроос үүнийг импортлож хандана:

import icsi301models from '../../modelData';

Санамж: <StrictMode> нь хөгжүүлэлтийн горимд алдааг эрт илрүүлэхийн тулд компонентын функц болон useEffect-ийг хоёр удаа ажиллуулдаг. Тиймээс console.log-ийн мэдэгдэл хоёр удаа хэвлэгдвэл энэ нь алдаа биш.

Даалгавар 1: Example харагдацыг ойлгох ба шинэчлэх (5 оноо)

getting-started.html харагдац болон Example компонентийг үзэж ойлгох хэрэгтэй. Өөрийгөө ойлгосон гэдгийг харуулахын тулд дараах зүйлсийг хийнэ:

  1. Example компонентийн модель өгөгдлийг "Unknown name" гэсний оронд өөрийн нэрээр шинэчлэнэ. "Unknown name" гэж хаана байгааг хайж болоод үүнийг солино (src/modelData/example.js).
  2. Example компонентод байгаа motto-update гэсэн класстай div элементийн агуулгыг таны нэр болон богино (20 тэмдэгт хүртэл) уриа үг (motto) харуулдаг JSX командаар солино. Хэрэглэгчийн нэртэй адилхан уриа үгний утга нь моделийн өгөгдлөөс гарч ирэх ёстой. Үүнийг дэлгэцлэх зарим загвар Example.css файлд бичээрэй.
  3. Өмнөх алхамаар хийсэн дэлгэцлэх хэсгийг хэрэглэгч өөрөө уриа үгийг шинэчилж болдог байхаар өргөтгөнө. Гарааны утга нь моделийн өгөгдлөөс гарч ирдэг байх ёстой. Уриа үгийг useState Hook-ээр төлөв болгон хадгална.

Даалгавар 2: Шинэ компонент үүсгэх - хот, аймгийн харагдац (10 оноо)

Өгөгдсөн тэмдэгт мөрийг агуулж байгаа Монгол улсын хот, аймгийн бүх нэрсийг дэлгэцлэх шинэ компонент үүсгэнэ. Таны харагдац тэмдэгт мөр авдаг оролтын талбартай байх ёстой. Харагдац нь тухайн тэмдэгт мөрийг агуулж байгаа (том жижиг үсгийн ялгаагүй) хот, аймгийн нэрсийг нэг жагсаалтад цагаан толгойн үсгийн дарааллаар дэлгэцлэнэ. Жишээ нь, тэмдэгт мөр нь "ан" гэсэн утгатай байвал Архангай, Булган, Дархан, Дархан-Уул, Завхан, Өвөрхангай, Улаанбаатар нэрс гарч ирнэ. Энэ хуудас хот, аймгийн нэрсийг шүүхэд хэрэглэсэн тэмдэгт мөр утгыг бас дэлгэцлэдэг байна. Хэрэв тохирох хот, аймгийн нэр олдохгүй бол веб хуудас нь холбогдох зурвасыг (юу ч харуулахгүй байхын оронд) харуулдаг байна. Тэмдэгт мөрийн утга хоосон бол бүх хот, аймгийн нэрийг харуулдаг байна.

Санамж: Unicode-д "Ө", "Ү" үсгүүд "Я"-гийн дараа байрладаг тул массивын энгийн sort() функц Өвөрхангай, Өмнөговийг жагсаалтын хамгийн сүүлд гаргана. Монгол цагаан толгойн дарааллаар эрэмбэлэхдээ localeCompare функцийг ашиглана:

names.sort((a, b) => a.localeCompare(b, 'mn'))
Шүүсэн жагсаалтыг тусад нь төлөвт хадгалах шаардлагагүй. Оролтын утгаас компонентыг рендерлэх үед тооцоолж болно. Жагсаалтын элемент бүрт key шинж өгөх хэрэгтэй.

Даалгавар #1-д өгсөн шиг хот, аймгийн нэрийг модель өгөгдөл болгож өгсөн байгаа. Үүнийг импортлосны дараа icsi301models.citiesProvincesModel() гэж хандаж болно:

import icsi301models from '../../modelData';

src/modelData/citiesProvinces.js файлаас хот, аймгийн нэрний өгөгдлийн форматын тайлбартай танилцаарай.

Энэ даалгаврыг эхлүүлэхэд туслах, чиглүүлэх зорилгоор src/p2.jsx файлыг холбож дуудсан p2.html файлыг нэрийн зохицолтойгоор бэлдэж өгсөн байгаа. src/p2.jsx нь CitiesProvinces React компонентийг дэлгэцлэнэ. Энэ хуудсыг веб хөтөч дээр http://localhost:5173/p2.html URL хаягаар дуудаж үзээрэй.

Таны хөгжүүлэх файлууд бол:

  • src/components/CitiesProvinces/CitiesProvinces.jsx - Хот, аймгийн харагдацыг хөгжүүлэх React компонент.
  • src/components/CitiesProvinces/CitiesProvinces.css - Компонентод шаардлагатай дурын CSS загварууд. Хот, аймгийн нэрийн жагсаалтыг харуулахад зарим загвар хэрэгжүүлэх ёстой.

Даалгавар 3: Байршлыг өөрчлөх (5 оноо)

Header нэртэй React компонент үүсгэнэ. Энэ нь харагдацын дээд хэсэгт веб аппын толгойг (header) дэлгэцлэдэг. Толгойг энэ даалгаварт байгаа React-ийн бүх компонентод (src/gettingStarted.jsx, src/p2.jsx, src/p4.jsx, src/p5.jsx) нэмж өгнө. Өмнөх даалгаврын эхний хэсгийг (таны нэр ба уриа үгтэй) өөрчлөхгүй. Тэр хэсэг нь толгойгоос тусдаа байх ёстой. Өөрийн төсөөлөл, бүтээлч байдлаараа "зөвхөн чинийх" гэж харагдах толгойг үүсгээрэй. Энэ нь нэмэлт зураг, график, юунд таалагдана, тэр бүгдийг агуулж болно. Та компонентууд дахь JSX/ЖаваСкриптийг өргөтгөх бөгөөд гаднын React компонент, ЖаваСкрипт санг, жишээ нь, JQuery, ашиглаж болохгүй. Бүтээлч байгаарай!

Таны хөгжүүлэх файлууд бол:

  • src/components/Header/Header.jsx - Толгойг хөгжүүлэх React компонент. Энэ нь JSX буцаадаг Header нэртэй function компонентоор тодорхойлогдоно (класс компонент биш).
  • src/components/Header/Header.css - Өөрийн компонентод хэрэгтэй ямар нэг CSS загварууд. Толгой компонентод заавал загвар тодорхойлж өгнө.
Санамж: getting-started.html нь хуудасны дээд талдаа Даалгавар 3-аар хийсэн толгойг агуулж байх ёстой. Даалгавар 1.2-оор хийсэн уриа үгтэй хэсэг нь үүний яг доор нь байна. Бусад хуудасны харагдацууд (p2.html, p4.html and p5.html) энэ толгойг холбосон байна.

Даалгавар 4: Харагдацуудыг динамикаар солих (10 оноо)

p4.html болон холбогдох JSX файлыг src/p4.jsx үүсгэнэ. Энэ нь хоёр харагдац компонентийг (Example болон CitiesProvinces компонент) агуулна. src/p4.jsx нь энэ хоёр компонентийг хооронд нь сольж харуулдаг байх хэрэгтэй. Нэг харагдац нь дэлгэцлэгдсэн байхад нөгөөг нь сольж дэлгэцлэх нэг товч (button) байна. Жишээ нь, CitiesProvinces дэлгэцлэгдсэн байхад үүний дээд талд байрлах товч нь "Example руу шилжих" гэж харагдах, товчийг дарахад CitiesProvinces алга болоод Example дэлгэцлэгддэг байна. Аль харагдац дэлгэцлэгдэж байгааг useState Hook-ээр хадгална.

Энэ даалгаврын хувьд дээрх файлуудыг үүсгэх хэрэгтэй. p4.html нь getting-started.html-тэй адилаар <script type="module" src="/src/p4.jsx"> гэж JSX файлаа холбоно. Хөгжүүлэлтийн горимд (npm run dev) шинэ хуудас нэмэлт тохиргоогүйгээр шууд ажиллана. Харин npm run build командаар багц үүсгэхэд vite.config.js файлын input жагсаалтад p4.html-ийг нэмж өгөх хэрэгтэй (комментоор бэлдсэн мөр бий).

Даалгавар 5: Нэг хуудаст апп (5 оноо)

Хэдийгээр Даалгавар 4-т гүйцэтгэсэн аргаар харагдац хооронд шилжиж болох ч энэ нь тухайн нэг харагдацыг заах URL-ийг хуваалцах (share) болон тэмдэглэж авах (bookmark) боломжийг олгохгүй. Веб хөтчийг дахин ачаалахад веб апп ямар хуудсыг дэлгэцэлж байсныг алдуулна.

Бид энэ дутагдлыг URL-д харагдацын мэдээллийг хадгалснаар шийдвэрлэх боломжтой. React Router нь React-д ийм функцээр хангаж өгдөг. Энэ даалгаврын хувьд p4.html файлаа p5.html, src/p4.jsx файлаа src/p5.jsx нэртэйгээр хуулбарлаж аваарай. Кодоо React Router модулийг ашиглан хоёр харагдацын хооронд нь сольж харуулдаг болгоно. Та тодорхой загвартай хэрэгслийн-мөр маягийн удирдлагатай (styled toolbar-like control) (энгийн бичвэр линк байх нь хангалтгүй) байх ёстой ба энэ нь хэрэглэгчид Example болон CitiesProvinces компонент харагдацыг сольж шилжих боломжийг олгодог байна.

Энэ бол бидний импортлож байгаа үндсэн React модулиас гаднах эхний өргөтгөл учир бид танд алхам нэг бүрийг нь тайлбарлаж өгье.

  1. Төслийн package.json файлд react-router (7-р хувилбар) модулийг тодорхойлсон учир npm install командаар аль хэдийнэ татаад авчихсан байгаа. Бид үүнийг src/p5.jsx файл дотроо импортлож оруулах ёстой. Дараах мөрүүдийг нэмнэ:
    import { HashRouter, Routes, Route, Link } from "react-router";
    Энэ мөр нь ЖаваСкрипт import командаар React Router-аас React компонентуудыг: HashRouter, Routes, Route, болон Link авч ирнэ. React Router-ийн HashRouter модуль URL-ийн ногдол хэсгийг (fragment portion) мэдээллийг хадгалах зорилгоор ашигладаг. Иймд бид CitiesProvinces харагдацыг илэрхийлэх p5.html#/cities-provinces, Example компонент харагдацыг тодорхойлох p5.html#/example тэмдгийг үүсгэж болно.
  2. React Router-ийг ашигладаг хамгийн түгээмэл арга нь одоогийн URL дээр нь түшиглээд үзүүлэх гэж байгаа харагдацаа нөхцөлтэй рендерлэх юм. Route компонентуудыг Routes дотор, Routes-ийг HashRouter дотор оруулж ийм нөхцөлт рендерлэлтийг хэрэгжүүлж болдог:
    <HashRouter>
      ...
      <Routes>
        <Route path="/cities-provinces" element={<CitiesProvinces />} />
        <Route path="/example" element={<Example />} />
      </Routes>
      ...
    </HashRouter>
    
    Хэрэв URL-д #/cities-provinces агуулж байвал CitiesProvinces, #/example гэж байвал Example компонентийг рендерлэнэ.
  3. Хэдийгээр бид хайперлинк (жишээ нь, <a> tags) ашиглаад харагдацыг сольж болох боловч react-router Link компонентоор хайперлинк үүсгэн ашиглахыг зөвлөдөг. Жишээ нь:
    <Link to="/cities-provinces">Хот, аймаг</Link>
    
    Дээрх код href="#/cities-provinces" утгатай, "Хот, аймаг" бичвэртэй хайперлинк үүсгэж өгнө. Идэвхтэй холбоосыг ялгаж загварчлах бол NavLink компонентийг ашиглаж болно.

Даалгавар 4-тэй харьцуулж үзээрэй: useState-ээр харагдац сольход URL өөрчлөгддөггүй тул веб хөтчийн "Буцах" (Back) товч ажиллахгүй, хуудсыг дахин ачаалахад эхний харагдац руу буцна. React Router-ийн тусламжтайгаар харагдац бүр өөрийн URL-тэй болж, тэмдэглэх, хуваалцах, "Буцах" товч бүгд ажиллана.

Загвар (5 оноо)

Энэ оноог лекц дээр хэлэлцсэн MVC загварын зөвлөмжийг дагаж зөв зохион байгуулсан тохиолдолд өгнө. Таны код DOM-д шууд хандаж удирдсан байж болохгүй. Нэмж хэлэхэд, таны код болон загвар цэвэрхэн, уншууртай байх ёстой. Илгээхээсээ өмнө ESLint багажийг ажиллуулсан байх хэрэгтэй. ESLint ямар нэг алдаа, санамж өгөөгүй байна. ESLint нь Hooks-ийн дүрмүүдийг (жишээ нь, Hook-ийг зөвхөн компонентын дээд түвшинд дуудах, useEffect-ийн dependency жагсаалтыг бүрэн бичих) мөн шалгадаг.

Хүлээлгэн өгөх үр дүн

5 дахь хэсгийг хэрэгжүүлсний дараа 1-ээс 4 хүртэл ажиллаж байгааг нягтлаарай!

Даалгавар илгээх зааврын дагуу аппаа бүхэлд нь (project4 хавтас доторх бүгд) илгээнэ. node_modules болон dist хавтсыг илгээх шаардлагагүй.