React reaktiv emas

Dasturlash dunyosida “reaktiv” atamasi turli narsalarni ifodalash uchun ishlatiladi, ammo odatda ma’lumotlar o’zgarishlariga avtomatik ravishda javob beruvchi tizimlarni tavsiflash uchun qo’llaniladi. Reaktiv dasturlash paradigmasi o’zgarishlarga javob beruvchi tizimlarni yaratishga va ushbu o’zgarishlarni tizim bo’ylab avtomatik ravishda tarqatishga qaratilgan. Shu sababli Vue.js va Svelte kabi freymvorklar ko’pincha reaktiv sifatida ta’riflanadi. Biroq, React an’anaviy reaktiv modelga amal qilmaydi va uning yondashuvi tubdan farq qiladi.

React foydalanuvchi interfeyslarini deklarativ tarzda yaratish uchun kutubxona sifatida paydo bo’lgan. Bu deklarativ uslub, React dasturchilarga faqat nimani xohlashini tavsiflash imkonini beradi va React qanday qilishni o’zi hal qiladi. React dasturchilarga joriy state’ga asoslangan foydalanuvchi interfeysini tavsiflash imkonini beradi va har safar state o’zgarganda UI’ni yangilaydi. Bu tavsif React’ni reaktivdek ko’rsatishi mumkin, ammo uning ichki mexanizmlariga chuqurroq kirishganimizda, React’ning modeli an’anaviy reaktiv dasturlash modelidan tubdan farq qilishini ko’ramiz.

An’anaviy reaktiv tizim

React’ning nima uchun an’anaviy reaktiv bo’lmasligini tushunish uchun, avval an’anaviy reaktivlikning qanday ishlashiga qaraylik. An’anaviy reaktiv tizimda hisob-kitoblar orasidagi qaramliklar avtomatik ravishda kodni ishlatishda kuzatiladi. Reaktiv qaramlik o’zgarganda, unga bog’liq barcha hisob-kitoblar o’zgarishni aks ettirish uchun avtomatik ravishda qayta bajariladi. Bu odatda ma’lumotlar bog’lanishi (data-binding), kuzatiluvchilar (observables), yoki signal va slotlar kabi texnikalar yordamida amalga oshiriladi.

Masalan, signal - bu reaktiv qiymat yaratish uchun ishlatiladigan reaktiv primitiv. O’qilganda signal o’quvchini obuna qiladi, yozishda esa barcha obunachilarga bildirishnoma yuboriladi. Bu reaktivlikning asosiy qoidasi (Reactivity 101) hisoblanadi.

Reactning yondashuvi

React state va uning yangilanishlarini boshqarish uchun boshqacha yondashuvni qo’llaydi. Qaramliklarni avtomatik ravishda kuzatish va o’zgarishlarni tarqatish o’rniga, React state’ni yangilash uchun yanada aniqroq mexanizmni - useState hook’ni kiritadi. State o’zgarganda, React darhol yangilanishlarni amalga oshirmay, qayta render qilishni rejalashtiradi va ushbu qayta render jarayonida butun komponent funksiyasi yangi state bilan qayta ishlaydi.

Reactning bu usuli reaktiv tizimlardan farq qilib, barcha qaramliklarni avtomatik kuzatmaydi va hisob-kitoblarni o’z-o’zidan qayta bajarishga asoslanmaydi.

1-misol: Counter komponenti

Ushbu hisoblagich misolida kod quyidagicha yozilgan:

import React, { useState } from "react";
 
function Counter() {
  const [count, setCount] = useState(0);
 
  function increment() {
    setCount(count + 1);
  }
 
  return (
    <div>
      <p>{count}</p>
      <button onClick={increment}>Increment</button>
    </div>
  );
}
 
export default Counter;

Bu misolda setCount chaqirilganda, Counter funksiyasi, shu jumladan useState hook ham qayta chaqiriladi. Bu an’anaviy reaktiv modeldan farq qiladi. An’anaviy reaktiv tizimda, butun funksiyani qayta chaqirish o’rniga, faqat UI’ning reaktiv qismlari yangilanardi. Bu holda faqat <p> ichidagi {count} yangilanishi kerak edi. Bu “yirik darajadagi reaktivlik” deb ataladi va bu signalning “mayda darajadagi reaktivlik” modeliga qarama-qarshi.

React tenglamasi

React ko’pincha quyidagi tenglama bilan ifodalanadi:

v = f(s)

Bu yerda, UI (v) uning state’i (s) funksiyasi sifatida aniqlanadi. Ushbu tenglama React’ning reaktiv emasligini ko’rsatadi: UI state’ning funksiyasi sifatida beriladi, lekin state o’zgarganda avtomatik ravishda yangilanmaydi. Buning o’rniga, UI faqat yangi state bilan funksiya qayta bajarilganda yangilanadi.

Virtual DOM va reconciliation jarayoni

Bu erda React virtual DOM’ni diffing va reconciliation jarayoni boshlanadi. Komponentning state’i yoki props o’zgarganda, React komponentni qayta render qiladi va yangi virtual DOM quyi daraxtini yaratadi. Keyin u yangi daraxtni eski daraxt bilan solishtiradi, real DOM’da kerakli minimal o’zgarishlarni aniqlaydi va ularni qo’llaydi.

Bu jarayon Reactning state’ni yangilash va UI o’zgarishlarini samarali ravishda boshqarishiga yordam beradi, lekin u an’anaviy reaktiv modelga o’xshamaydi, chunki UI avtomatik tarzda yangilanmaydi va butun funksiyani qayta chaqirish talab qilinadi.

Bu modelda state aniq o’rnatilib, qayta render qilinadi. Boshqa reaktiv tizimlardan farqli ravishda o’zgarishlar avtomatik ravishda tarqatilmaydi, bu esa oldindan ko’ra olish imkoniyatini oshiradi. Agar React inson qiyofasida tasavvur qilinsa, u shunday deya oladi: “Menga state kutishlaringizni ayting, men uni boshqaraman.” Bu yondashuv state yangilanishlarini guruhlash kabi xususiyatlarini yoqadi va ilova state’ini istalgan vaqtda tushunishni osonlashtiradi, chunki state yangilanishi va natijadagi UI yangilanishi yagona, atom operatsiyasida bog’langan bo’ladi.

Biroq, bu model React komponentlarini an’anaviy ma’nodagi reaktivlikdan uzoqlashtiradi. Ular ma’lumotlar o’zgarishlariga avtomatik tarzda reaksiyaga kirmaydi. Buning o’rniga, React aynan shu state uchun UI qanday ko’rinishi kerakligini aniqlab beradi va state o’zgarganda, kerakli yangilanishlarni amalga oshirish uchun butun funksiyani qayta ishga tushiradi. Bu, faqat mos qiymatlar joyida yangilanadigan avtomatik reaktiv tarqatishdan farq qiladi.

React’ning reaktiv bo’lmagan yondashuvi

React avtomatik o’zgarishlarni kuzatish va tarqatish jihatidan reaktiv bo’lmasa-da, dinamik va interaktiv foydalanuvchi interfeyslarini yaratish uchun samarali mexanizmni taqdim etadi. State va props orqali renderni boshqarish, o’zgarishlarning ilovada qanday tarqalishini tushunishda aniq va ishonchli modelni ta’minlaydi, va virtual DOM tizimi real DOM’ni samarali boshqarish uchun yangilanishlarni amalga oshiradi.

Yakunida, React yondashuvi reaktivlik deb atalishi yoki atalmasligi semantikaga bog’liq. Agar reaktivlikni tizim orqali o’zgarishlarni avtomatik tarqatish deb tushunsangiz, unda, ha, React reaktiv emas. Ammo reaktivlikni tizimning state o’zgarishlariga oldindan aytib bo’ladigan va nazoratli tarzda javob berish qobiliyati sifatida tushunsangiz, unda React reaktiv deb hisoblanishi mumkin.

React va boshqa freymvorklar yoki kutubxonalarni ko’rib chiqsak, UI ishlab chiqishda state va reaktivlikni boshqarishda yagona yondashuv yo’qligi aniq bo’ladi. Har bir vosita o’zining kuchli tomonlari va kamchiliklariga ega va turli holatlar uchun mos keladi. Ushbu farqlarni tushunish to’g’ri vositani tanlash uchun muhimdir va qaysi freymvork yoki kutubxonadan foydalanganingizdan qat’i nazar, samarali va effektiv kod yozishga yordam beradi.

React’ning state’ni boshqarish va yangilanish modeli boshqaruv va qulaylik o’rtasidagi ajoyib muvozanatni ta’minlaydi. State’ni aniq yangilash mexanizmi dasturchilarga dastur holati haqida osonroq fikr yuritish imkonini beradi, shu bilan birga, reconciliation va farqlash(diffing) algoritmi yangilanishlarni DOM’ga samarali qo’llaydi. An’anaviy ravishda “reaktiv” bo’lmasa-da, React’ning yondashuvi murakkab foydalanuvchi interfeyslarini yaratishda juda samarali ekanligini isbotladi.

Reaktiv dasturlash modeli va Solid misoli

Reaktiv dasturlash modellari, ayniqsa, avtomatik ravishda qaramliklarni va yangilanishlarni boshqarish haqida gap ketganda, bir qator inkor etib bo’lmas afzalliklarni taqdim etadi. Ammo biz ko’rganimizdek, React yondashuvi o’zining yuqori darajadagi nazorat va oldindan ko’ra oluvchanlik qobiliyatlari bilan birga keladi.

To’liq qilish uchun, endi Solid freymvorkida qanday qilib bir xil hisoblagich ko’rinishini ko’rib chiqamiz:

import { createSignal } from "solid";
 
function Counter() {
  const [count, setCount] = createSignal(0);
 
  function increment() {
    setCount(count() + 1);
  }
 
  return (
    <div>
      <p>{count()}</p>
      <button onClick={increment}>Increment</button>
    </div>
  );
}
 
export default Counter;

Ushbu misolda, count komponentning ma’lumotlarining reaktiv xususiyati hisoblanadi. Biz count ni count() sifatida chaqirish orqali o’qiganimizda, bu JSX’ning ushbu qismiga reaktiv qiymatga bilvosita obuna bo’lamiz.

Keyinchalik, biz increment()ni chaqirganimda, setCount chaqiriladi va setCount qiymatni yangilaydi va barcha obunachilarni o’zgarish haqida xabardor qiladi, bu esa ularga yangilanishni amalga oshirishni talab qiladi. Bu, obunachi va nashr etuvchi o’rtasidagi munosabatni ifodalovchi “pub/sub” modeliga o’xshaydi.

Natijada, yuqori tafsiliy darajadagi reaktivlik (fine-grained reactivity) yuzaga keladi: ya’ni, funksiya komponenti, Counter, bir martadan ortiq chaqirilmaydi, lekin nozik va kichik reaktiv qiymatlar chaqiriladi.

2- misol: O’zaro bog’liq qiymatlar (Dependent values)

Keling, mahsulotlar ro’yxatini va ularning sonini ko’rsatadigan komponentni ko’rib chiqamiz. Svelte kabi reaktiv tizimda, ro’yxat o’zgarganda, son avtomatik ravishda yangilanadi:

<script>
    let items = ['Apple', 'Banana', 'Cherry'];
    $: count = items.length;
</script>
 
<p>{count} items:</p>
<ul>
  {#each items as item (item)}
    <li>{item}</li>
  {/each}
</ul>

Bu yerda $: count = items.length; reaktiv bayonotni e’lon qiladi. items o’zgarganda, count avtomatik ravishda qayta hisoblanadi.

React’da bu biroz boshqacha ko’rinadi:

import React, { useState } from "react";
 
function ItemList() {
  const [items, setItems] = useState(["Apple", "Banana", "Cherry"]);
  const count = items.length;
 
  // ... elementlarni biror joyda yangilash ...
 
  return (
    <div>
      <ul>
        <p>{count} items:</p>
        {items.map((item) => (
          <li key={item}>{item}</li>
        ))}
      </ul>
    </div>
  );
}
 
export default ItemList;

Bu React komponentida, count qiymati items o’zgarganda avtomatik yangilanadigan reaktiv qiymat emas. Buning o’rniga, bu joriy state’dan yaratilgan qiymat bo’lib, u render bosqichida hisoblanadi. items o’zgarganda, biz setItemsni chaqirib, state’ni yangilashimiz va qayta render qilishimiz kerak. Bu vaqtda count qayta hisoblanadi, lekin bu count reaktiv bo’lganligi sababli emas, balki ItemList funksiya komponenti qayta chaqirilganda bo’ladi.