React-ի useCallback կատարողականության օպտիմիզացիայի հուք

Այս դասում մենք կդիտարկենք կատարողականության օպտիմիզացիայի հետևյալ հուքը՝ useCallback։

useCallback հուքը նման է useMemo API-ին, տարբերությունն այն է, որ առաջինը կեշավորում է արժեքը էկրանի վերագծման պահերի միջև, իսկ երկրորդը՝ կոլբեքը։ Սա մեզ թույլ է տալիս չվերագործարկել ռեսուրսատար ֆունկցիաները, երբ դա պահանջված չէ, և կարող է օգտագործվել ֆունկցիան դուստր կոմպոնենտներին անցկացնելիս։

Եկեք մանրամասն հասկանանք օրինակով։ Սկսելու համար ստեղծենք App կոմպոնենտը և դրանում ստեղծենք num սթեյթը։

App.jsxconst [num, setNum] = useState(0);

Եկեք ունենանք կոճակ, որի սեղմումով num-ը մեծանում է 1-ով, և պարբերություն, որտեղ մենք կցուցադրենք num-ի արժեքը։

App.jsxreturn (
  <div>
    <button onClick={() => setNum(num + 1)}>click</button>
    <p>clicks: {num}</p>
  </div>
);

Հիմա, ենթադրենք, որ մեր App-ում ցուցադրվում է ինչ-որ ցուցակ տարրերով, որը մենք կլրացնենք մեկ այլ կոճակի սեղմումով։ Այս ցուցակի տարրերը պահելու համար մենք կստեղծենք items սթեյթը։

App.jsxconst [items, setItems] = useState([]);

Ապա գրենք addItem ֆունկցիան դրանք ավելացնելու համար։

App.jsxfunction addItem() {
  setItems([...items, 'new item']);
}

Հիմա եկեք գրենք ցուցակի տարրերը ցուցադրելու կոդը և այն տեղափոխենք Items դուստր կոմպոնենտ, որը պրոպսների միջոցով կստանա տարրերի զանգվածը և դրանք ավելացնելու ֆունկցիան։ Եկեք չմոռանանք ավելացնել տպում կոնսոլում, որպեսզի տեսնենք թե երբ է մեր Items կոմպոնենտը վերագծվում։

Items.jsxfunction Items({ items, addItem }) {

  const result = items.map((item, index) => {
    return <p key={index}>{item}</p>;
  });
  
  console.log('Items render');
  
  return (
    <div>
      <h3>Our items</h3>
      {result}
      <button onClick={addItem}>add item</button>
    </div>
  );
}

export default Items;

Տեղադրենք Items-ը App կոմպոնենտի վերջում և նրան կանցկացնենք items զանգվածը և տարրեր ավելացնելու addItem ֆունկցիան։

App.jsxreturn (
  <>
    <div>
      <button onClick={() => setNum(num + 1)}>click</button>
      <p>clicks: {num}</p>
      <br />
    </div>
    <Items items={items} addItem={addItem} />
  </>
);

Հիմա եկեք սեղմենք կոճակների վրա և համոզվենք, որ num-ը աճում է և նոր տարրեր ավելանում են ցուցակին։ Իսկ կոնսոլը բացելով՝ մենք կտեսնենք, որ մեր ցուցակը վերագծվում է ամեն անգամ, նույնիսկ եթե մենք սեղմում ենք այն կոճակի վրա, որը մեծացնում է num-ը։

Եթե մենք ունենք փոքր ցուցակ, ապա ամեն ինչ կարգին է, բայց եթե ենթադրվում է, որ այն մեծ ծավալի կլինի և այնտեղ դեռ շատ այլ բաներ կան։ Վատ բան չէ՝ կասեք դուք, քանի որ նախորդ դասին մենք դիտարկեցինք memo API-ը, որպեսզի խուսափենք կոմպոնենտի ավելորդ վերագծումներից։

Ուրեմն եկեք փաթաթենք մեր Items կոմպոնենտը memo-ի մեջ և ամեն բան կլինի։ Ի դեպ, դա կարելի է անել անմիջապես Items-ը էքսպորտելիս։

Items.jsxexport default memo(Items);

Եկեք չմոռանանք իմպորտել memo-ը։

Items.jsximport { memo } from 'react';

Հիմա բացենք կոնսոլը և սեղմենք կոճակների վրա։ Բոլոր ջանքերը ապարդյուն։ Մենք մեմոիզացրել ենք կոմպոնենտը, բայց 'click' կոճակը սեղմելիս Items կոմպոնենտը այնուամենայնիվ վերագծվում է ամեն անգամ։

Բանն այն է, որ երբ ծնող կոմպոնենտը վերագծվում է, նրա ֆունկցիաները կրկին ստեղծվում են - սա վերաբերում է նաև մեր addItem ֆունկցիային, որը մենք անցկացնում ենք Items-ին։

Հենց այս պահին մեզ կօգնի useCallback հուքը։ Եկեք կիրառենք այն։ Սկսելու համար իմպորտենք այն App-ում։

App.jsximport { useCallback } from 'react';

Ապա փոխակերպենք ֆունկցիայի պարզ հայտարարությունը addItem-ում Function Expression-ի, որպես առաջին պարամետր useCallback-ի համար նշենք մեր ֆունկցիան կոլբեքի տեսքով։ Երկրորդ պարամետրում քառակուսի փակագծերում նշենք կախվածությունները - բոլոր ռեակտիվ փոփոխականները, որոնք մասնակցում են ֆունկցիայում, մեր դեպքում դա items զանգվածն է։

App.jsxconst addItem = useCallback(() => {
  setItems(() => [...items, 'New item']);
}, [items]);

Պատրաստ է։ Այսպիսով մենք կեշավորել ենք ֆունկցիան։ Կրկին սեղմենք կոճակների վրա և տեսնենք, որ այժմ 'click' կոճակը սեղմելիս մեր դուստր կոմպոնենտը չի վերագծվում։

Задание 1

Ստեղծեք App կոմպոնենտը, տեղադրեք դրա մեջ տեքստով պարբերություն։ Ստեղծեք սթեյթ 'text' սկզբնական արժեքով և ցուցադրեք այն պարբերությունում։ Թող պարբերության վրա սեղմելիս նրա տեքստի վերջում ավելանա բացականչական նշան։

Задание 2

Ստեղծեք դուստր կոմպոնենտ Products, որում դուք կունենաք նոր ապրանք ավելացնելու կոճակ։ Տեղադրեք այն App-ում։ Ծնող կոմպոնենտում ստեղծեք սթեյթ ապրանքների զանգվածով և նոր ապրանք ավելացնելու ֆունկցիա։ Անցկացրեք դրանք որպես պրոպսներ դուստր կոմպոնենտին, ցուցադրեք դրանում անցկացված զանգվածը որպես ul ցուցակ։

Задание 3

Products-ում տպեք կոնսոլում 'products render' տեքստը։ Փաթաթեք Products-ը memo-ի մեջ։ Սեղմեք պարբերության և կոճակի վրա։ Համոզվեք, որ պարբերության վրա սեղմելիս դուստր կոմպոնենտը այնուամենայնիվ վերագծվում է։

Задание 4

Կեշավորեք ապրանքներ ավելացնելու ֆունկցիան՝ փաթաթելով այն useCallback հուքի մեջ։ Սեղմեք պարբերության և կոճակի վրա։ Համոզվեք, որ պարբերության վրա սեղմելիս դուստր կոմպոնենտը այլևս չի վերագծվում։