React-da voqea ishlov beruvchilarini bog'lashning eng yaxshi usuli

Tasvir: Flickr by liz west

React-da bog'lash hodisalarini qayta ishlash murakkab bo'lishi mumkin (buning uchun sizda Javascript mavjud). Perl va Python tarixini bilganlar uchun TMTOWTDI (Buni amalga oshirishning yana bir yo'li bor) va TOOWTDI (buni amalga oshirishning faqat bitta yo'li bor) tanish so'zlar bo'lishi kerak. Afsuski, hech bo'lmaganda voqealarni bog'lab turish uchun JavaScript bu TMTOWTDI tili bo'lib, uni ishlab chiqaruvchilar har doim chalkashtirib yuborishadi.

Ushbu postda biz React-da voqea bog'lamalarini yaratishning keng tarqalgan usullarini ko'rib chiqamiz va sizga ularning ijobiy va salbiy tomonlarini ko'rsataman. Eng muhimi, sizga "Yagona Yo'l" ni topishga yordam beraman - yoki hech bo'lmaganda mening sevimli.

Ushbu xabar siz bog'lash zarurligini, masalan, buni nima uchun qilishimiz kerakligini tushunadi deb taxmin qiladi (masalan) yoki () {console.log (this) funktsiyasi o'rtasidagi farq; } va () => {console.log (bu); }. Agar siz ushbu savollarni chalkashtirsangiz, Saurabh Misra ularni ajoyib tarzda izohlab berdi.

Rasmda dinamik ulanish ()

Odatda ishlatiladigan birinchi holat bu (.) Funktsiyasidagi .bind (this) ni chaqirish. Masalan:

HelloWorld klassi {komponentini kengaytiradi {
  handleClick (voqea) {}
  render () {
    qaytish (
      

Assalomu alaykum, {this.state.name}!

       ni bosing     );   } }

Albatta, bu ishlaydi. Ammo bitta narsani o'ylab ko'ring: agar bu.state.namechanges bo'lsa nima bo'ladi?

Siz ushbu.state.name nomini o'zgartirsangiz, tarkibiy qism qayta ko'rsatiladi (). Yaxshi. Komponent nom qismini yangilash uchun xizmat qiladi. Ammo tugma ko'rsatiladimi?

React Virtual DOM-dan foydalanayotganiga e'tibor bering. Render paydo bo'lganda, u yangilangan Virtual DOM-ni oldingi Virtual DOM bilan taqqoslaydi va keyin faqat o'zgartirilgan elementlarni haqiqiy DOM daraxtiga yangilaydi.

Bizning holatda, render () chaqirilganda, ushbu.handleClick.bind (this) ishlov beruvchini bog'lash uchun ham chaqiriladi. Ushbu chaqiruv birinchi marta chaqirilganda (() birinchi marta chaqirilganda ishlatilgan ishlov beruvchidan mutlaqo farq qiladigan yangi ishlov beruvchini yaratadi.

Dinamik ulanish uchun virtual DOM. Moviy rangdagi elementlar qayta namoyish etiladi.

Yuqoridagi diagrammada bo'lgani kabi, render () ilgari chaqirilganida, this.handleClick.bind (bu) funktsiyani qaytarib berdi, shunda React onChange ning funktsa ekanligini bildi.

Keyinchalik, render () yana chaqirilganda, this.handleClick.bind (this) return funkB (har safar chaqirilganda yangi funksiyani qaytaradi). Shunday qilib, React onChange endi funkA emasligini, ya'ni tugmani qayta ko'rsatish kerakligini biladi.

Bitta tugma muammo bo'lmasligi mumkin. Agar sizda ro'yxatda 100 ta tugma bo'lsa-chi?

render () {
  qaytish (
    {this.state.buttons.map (btn => (
      
        {btn.label}
      
    ))}
  );
}

Yuqoridagi misolda, har qanday tugma yorlig'ini o'zgartirish barcha tugmachalarni qayta ko'rsatilishiga olib keladi, chunki barcha tugmalar yangi onChange ishlov beruvchisini yaratadi.

Quruvchi bilan bog‘lash ()

Eski maktab usuli - bu konstruktor bilan bog'lanish. Hech narsa o'ylamang:

HelloWorld klassi {komponentini kengaytiradi {
  konstruktor () {
    this.handleClick = this.handleClickFunc.bind (bu);
  }
  render () {
    qaytish ();
  }
}

Bu usul avvalgisiga qaraganda ancha yaxshi. Call (render ()) onClick uchun yangi ishlov beruvchini yaratmaydi, shuning uchun tugma o'zgarmasa, qayta ko'rsatilmaydi.

Virtual DOM konstruktor bilan bog'lash uchun. Moviy rangdagi elementlar qayta namoyish etiladi.

Ok funktsiyasi bilan bog'lang

ES7 klassi xususiyatlari bilan (hozirgi vaqtda Babel bilan qo'llab-quvvatlanadi) biz usulni aniqlashda bog'lay olamiz:

HelloWorld klassi {komponentini kengaytiradi {
  handleClick = (voqea) => {
    console.log (this.state.name);
  }
  render () {
    qaytish ()
  }
}

Yuqoridagi kodda, holdClick bu mos keladigan vazifadir:

konstruktor () {
  this.handleClick = (voqea) => {...} ;
}

Shunday qilib, komponent boshlangandan so'ng, this.handleClick hech qachon o'zgarmaydi. Shunday qilib, u qayta ko'rsatilmasligini ta'minlaydi. Ushbu yondashuv, ehtimol bog'lashning eng yaxshi usuli hisoblanadi. Oddiy, o'qish oson va eng muhimi, u ishlaydi.

Bir nechta elementlar uchun Ok funktsiyasi bilan dinamik bog'lash

Xuddi shu strelka funktsiyasidan foydalanib, bir nechta kirish uchun bir xil ishlov beruvchidan foydalanishimiz mumkin:

HelloWorld klassi {komponentini kengaytiradi {
  handleChange = name => voqea => {
    this.setState ({[[nomi]: event.target.value});
  }
  render () {
    qaytish (
      
      
    )
  }
}

Bir qarashda, bu soddaligi tufayli juda ajoyib ko'rinadi. Ammo, agar ehtiyotkorlik bilan o'ylasangiz, unda birinchi yondashuv bilan bir xil muammo borligini ko'rasiz: har safar render () ikkalasi ham "Chiqish> deb nomlanadi.

Haqiqatan ham, menimcha, bu yondashuv aqlli va men har bir maydon uchun bir nechta tutqichliXXXChange yozishni xohlamayman. Yaxshiyamki, ushbu ro'yxatda "ko'p ishlatiladigan ishlov beruvchi" turi kamroq ko'rinadi. Bu shuni anglatadiki, qayta ko'rsatiladigan tarkibiy qismlarining faqat ikkitasi bo'ladi va ehtimol ishlashda muammo bo'lmaydi.

Qanday bo'lmasin, uning bizga keltiradigan foydalari ishlash qobiliyatini yo'qotishdan ancha katta. Shuning uchun men ushbu yondashuvdan bevosita foydalanishni taklif qilaman.

Agar bu ishlash muammolari muhim bo'lib qolsa, men bog'lash paytida ishlov beruvchilarga keshlashni tavsiya qilaman (lekin bu kodni kamroq o'qiydi):

HelloWorld klassi {komponentini kengaytiradi {
  handleChange = name => {
    if (! this.handlers [name]) {
      this.handlers [name] = voqea => {
        this.setState ({[[nomi]: event.target.value});
      };
    }
    return this.handlers [name];
  }
  render () {
    qaytish (
      
      
    )
  }
}

Xulosa

React-da voqea bog'lamalarini amalga oshirayotganda, ishlov beruvchilarning dinamik ravishda yaratilganligini juda ehtiyotkorlik bilan tekshirishimiz kerak. Odatda, ta'sirlangan komponentlar bir yoki ikki marta paydo bo'lganda, bu muammo bo'lmaydi. Ammo voqea ishlovchilari ro'yxatda paydo bo'lganda, bu ishlashning jiddiy muammolariga olib kelishi mumkin.

Yechimlar

  • Iloji bo'lsa, o'q vazifasini bog'lang
  • Agar siz bog'lamalarni dinamik ravishda ishlab chiqarishingiz kerak bo'lsa, bog'lovchilar ishlash muammosiga aylansa, ishlov beruvchilarni keshlashni ko'rib chiqing

O'qiganingiz uchun rahmat! Ushbu post foydali bo'lgan deb umid qilaman. Agar siz ushbu xabarni foydali deb bilsangiz, tavsiya qilish orqali uni ko'proq odamlarga baham ko'ring.

Yangilash:

Omri Luzon va Shesh qulayroq bog'lash uchun lodash-dekorativ va reaktsion-avtobind paketlarini aytib o'tishdi. Shaxsan men avtomatik ravishda biron bir narsa qilishning katta muxlisi emasman (har doim bunday ulanishlarni minimal darajada saqlashga harakat qilaman), lekin avtomatik bog'lab qo'yish - bu toza kodni yozish va ko'proq harakatlarni tejashning juda yaxshi usuli. Kod quyidagicha bo'ladi:

'Reaktiv-avtobind' -dan autoBind-ni import qilish;
sinf HelloWorld () {
  konstruktor () {
    autoBind (bu);
  }
  handleClick () {
    ...
  }
  render () {
    qaytish ();
  }
}

AutoBind avtomatik bog'lovchilar bilan bog'langanligi sababli, bog'lanishni bajarish uchun strelka funktsiyasidan foydalanishning hojati yo'q (renderClick = () => {}) va render () funktsiyasidan this.handleClick-dan to'g'ridan-to'g'ri foydalanish mumkin.