React

JSX va komponentlar

React'da interfeysni tasvirlash uchun maxsus sintaksis โ€” JSX ishlatiladi. Bu birinchi qarashda HTML ichida JavaScript kabi ko'rinadi, lekin aslida bu โ€” JavaScript'ning kengaytmasi. Ushbu darsda JSX qanday ishlashini, komponentlarni qanday yozish va ekranga chiqarishni o'rganamiz.

JSX nima?

JSX (JavaScript XML) โ€” bu JavaScript kodining ichida HTML'ga o'xshash markup yozish imkonini beruvchi sintaksis. Masalan, quyidagi qator โ€” bu JSX:

const element = <h1>Salom, dunyo!</h1>;

E'tibor bering: bu na string (tirnoqsiz), na oddiy HTML. Bu โ€” JSX. Brauzer JSX'ni to'g'ridan-to'g'ri tushunmaydi. Vite ichidagi build vositasi (Babel) JSX'ni oddiy JavaScript funksiya chaqiruvlariga aylantiradi. Yuqoridagi kod aslida shunga o'giriladi:

const element = React.createElement("h1", null, "Salom, dunyo!");

Ya'ni JSX โ€” bu shunchaki React.createElement uchun qulay, o'qilishi oson yozuv usuli. Uni ishlatish majburiy emas, lekin deyarli barcha React kodi JSX bilan yoziladi, chunki u ancha qulay.

JSX โ€” string emas! Uni tirnoq ichiga olmang. <h1>Salom</h1> to'g'ri, "<h1>Salom</h1>" esa oddiy matn (string) bo'lib qoladi.

Funksional komponent

React'da komponent โ€” bu JSX qaytaruvchi oddiy JavaScript funksiyasi. Bunday komponentlar funksional komponentlar deb ataladi. Ular quyidagi ikki qoidaga bo'ysunadi:

Mana eng oddiy komponent:

function Salom() {
  return <h1>Salom, React!</h1>;
}

Ochilgan strelka funksiya (arrow function) shaklida ham yozish mumkin โ€” natija bir xil:

const Salom = () => {
  return <h1>Salom, React!</h1>;
};

Endi bu komponentni boshqa JSX ichida xuddi HTML teg kabi ishlatish mumkin. Diqqat: komponent teglari o'zini yopishi (/> bilan) mumkin:

function App() {
  return (
    <div>
      <Salom />
      <Salom />
      <Salom />
    </div>
  );
}
Komponentni bir marta yozib, uni istagancha ko'p marta ishlatish mumkin. Bu โ€” komponentlarning asosiy kuchi: qayta ishlatiluvchanlik.

Komponentni ekranga render qilish

Komponentni yozdik โ€” endi uni ekranga chiqarish kerak. Buning uchun React'ning react-dom/client qismidan createRoot funksiyasidan foydalanamiz. Avvalo HTML faylida bitta "ildiz" element bo'lishi kerak (Vite loyihasida u tayyor keladi):

<!-- index.html -->
<div id="root"></div>

Endi asosiy JavaScript faylida (Vite'da src/main.jsx) shu root elementiga komponentni ulaymiz:

import { createRoot } from "react-dom/client";
import App from "./App.jsx";

const root = createRoot(document.getElementById("root"));
root.render(<App />);

Bu kod nima qiladi? createRoot โ€” bizning React ilovamiz uchun "ildiz" tayinlaydi. root.render(<App />) esa App komponentini shu ildiz ichida chizadi. Shu tariqa butun ilova #root divi ichida yashaydi.

Eski React (17 va undan oldingi) versiyalarida ReactDOM.render() ishlatilardi. React 18'dan boshlab createRoot standart usul hisoblanadi.

Bitta ildiz element qoidasi

JSX'ning muhim qoidasi: komponent faqat bitta ildiz elementni qaytarishi kerak. Quyidagi kod xato beradi, chunki ikkita element yonma-yon turibdi:

// XATO!
function Profile() {
  return (
    <h1>Ism</h1>
    <p>Tavsif</p>
  );
}

Buni tuzatish uchun elementlarni bitta o'rovchi ichiga olamiz โ€” masalan, <div>:

function Profile() {
  return (
    <div>
      <h1>Ism</h1>
      <p>Tavsif</p>
    </div>
  );
}

Lekin ba'zan ortiqcha <div> qo'shishni istamaymiz. Bunday holda Fragmentdan foydalanamiz โ€” bo'sh teg <>...</>. U DOM'ga hech qanday qo'shimcha element qo'shmaydi:

function Profile() {
  return (
    <>
      <h1>Ism</h1>
      <p>Tavsif</p>
    </>
  );
}
JSX'ni bir necha qatorga yozganingizda, uni return ( ... ) qavslari ichiga oling. Bu JavaScript'ning avtomatik nuqta-vergul qo'yishi (ASI) sabab yuzaga keladigan xatolardan saqlaydi.

className va HTML atributlaridagi farqlar

JSX HTML'ga o'xshasa-da, aslida u JavaScript. Shuning uchun ba'zi HTML atributlari boshqacha yoziladi. Eng muhim farqlar:

// HTML: <div class="card">
// JSX:
function Card() {
  return <div className="card">Kontent</div>;
}
Agar class deb yozib qo'ysangiz, React ogohlantirish beradi, lekin ilova baribir ishlashi mumkin. Odat sifatida darrov className yozishga o'rganing.

JSX ichida JavaScript ifodalari โ€” {}

JSX'ning eng kuchli tomoni โ€” uning ichiga JavaScript qiymatlarini joylashtirish mumkinligi. Buning uchun jingalak qavslar { } ishlatiladi. Qavs ichiga istalgan JavaScript ifodasini (expression) yozish mumkin:

function Salom() {
  const ism = "Ali";
  return <h1>Salom, {ism}!</h1>;
}
// Natija: Salom, Ali!

Qavs ichida nafaqat o'zgaruvchi, balki har qanday ifoda bo'lishi mumkin โ€” matematik amal, funksiya chaqiruvi, xossaga murojaat:

function Hisob() {
  const a = 5;
  const b = 3;
  return (
    <div>
      <p>Yig'indi: {a + b}</p>
      <p>Sana: {new Date().getFullYear()}</p>
      <p>Katta harf: {"salom".toUpperCase()}</p>
    </div>
  );
}

Atributlarga ham qiymat berish uchun { } ishlatiladi (tirnoq o'rniga):

function Rasm() {
  const url = "logo.png";
  return <img src={url} alt="Logo" />;
}
Qavs ichiga faqat ifoda (expression โ€” qiymat qaytaradigan narsa) yozish mumkin. if, for kabi buyruqlar (statements) to'g'ridan-to'g'ri ishlamaydi. Shart uchun ternar operator (? :) ishlatiladi (bu haqda oxirgi darsda gaplashamiz).

Xulosa