Այս հոդվածում մենք կուսումնասիրենք, թե երբ և ինչպես օգտագործել React-ի useMemo Hook-ը՝ ձեր հավելվածի արդյունավետությունը բարձրացնելու համար:

TL;DR

Եթե ​​դուք այստեղ եք բացառապես հասկանալու համար, թե երբ (և ոչ) օգտագործել useMemeo և չեք ցանկանում աշխատել օրինակների միջոցով, ես ձեզ կխնայեմ: Համաձայն React Docs-ի, useCallback-ի նման, useMemo opt-inգործունակության բարելավիչ Hook-ն է, որն օգտագործվում է ֆունկցիաների արդյունքների համար ռեֆերենցիոն հավասարություն ստեղծելու համար: Ամենատարածված օգտագործման երեք դեպքերն են.

  1. եթե հաշվարկը ձեր հավելվածի այլ մասերում նկատելի դանդաղում է առաջացնում
  2. եթե հաշվարկը փոխանցում եք որպես երեխայի բաղադրիչ
  3. եթե հաշվարկն օգտագործվում է որպես կախվածություն Hook-ում

Եթե ​​այդ պայմաններից ոչ մեկը չի բավարարվում, դուք, ամենայն հավանականությամբ, կկորցնեք ժամանակ, տողեր և զոհաբերում եք ընթերցանությունը (և հիշողությունը)՝ ակտիվորեն «օպտիմալացնելով» ձեր հավելվածը:

Քանի որ դա բացակայում է, Եկեք սկսենք:

Սկսել

Կցեք և ամրացրեք ժապավենը:

Եթե ​​ցանկանում եք հետևել ձեր տեղական IDE-ին, կարող եք գտնել GitHub Repo-ն այստեղ: Հակառակ դեպքում, դուք կարող եք հղում կատարել կոդի հատվածներին, թեև բաց կթողնեք կատարողականի համեմատությունները:

  • fork and clone
  • cd client
  • npm i
  • npm start

Մեկնարկի կոդը

Մենք կսկսենք մեր մեկնարկային կոդի արագ ակնարկով: App.js-ում դուք կգտնեք «jacobsthal» անունով ֆունկցիա, վիճակի երկու կտոր և «calculation» անունով փոփոխական: Ուշադրություն դարձրեք, որ մենք jacobsthal-ը փաթաթել ենք useCallback Կեռիկի մեջ, և calculationjacobsthal կանչից վերադարձված արժեքն է:

JSX-ը ներկայացնում է և՛ մուտքերը, և՛ դրանց համապատասխան արժեքները: Եթե ​​Ձեզ անհրաժեշտ է թարմացում, թե ինչ ծառայություն է մատուցում useCallback Hook-ը, ես կառաջարկեի կանգ առնել այստեղ և արագ կարդալ իմ useCallback հոդվածը:

Մեր jacobsthal ֆունկցիան պարզ, ռեկուրսիվ ֆունկցիա է, որը վերադարձնում է Jacobsthal Number-ը տվյալ ինդեքսում: Կոդի առանձնահատկությունները և Jacobsthal Number-ը նշանակություն չունեն useMemo-ի համար: Մեզ հետաքրքրում է միայն այն, որ այն սահմանված է մեր բաղադրիչի ներսում, հետևաբար՝ useCallback-ի իրականացումը, և որ այն հաշվողականորեն թանկ է:

Եթե ​​մենք փոքր արժեք տրամադրենք number մուտքագրմանը, մեր React հավելվածն իրեն պահում է այնպես, ինչպես սպասվում էր՝ արագորեն ցույց տալով արդյունքը: Այնուամենայնիվ, քանի որ մենք մեծացնում ենք մեր մուտքագրման արժեքը, մինչդեռ հավելվածը դեռ ապահովում է ցանկալի արդյունքը, այն ավելի ու ավելի երկար է տևում մատուցման համար:

Ինչու է դա տեղի ունենում:

Երեսունհինգը կլինի մեր փորձնական դեպքը, քանի որ այն բավական դանդաղ է, որպեսզի նյարդայնացնի, բայց դեռ փորձարկվող: Այսպիսով, մենք կգրենք 35 և կսպասենք, որ մեր արդյունքը հաշվարկվի:

Այժմ սկսեք մուտքագրել երկրորդ մուտքագրման մեջ: Տեսնու՞մ եք, թե որքան դանդաղ է այն ցուցադրվում: Դա պայմանավորված է նրանով, որ երբ ներածումը փոխվեց, ամբողջ բաղադրիչը նորից ներկայացվեց, և մեր թանկարժեք ֆունկցիան վերահաշվարկեց ելքը մինչև վերաարտադրումը, չնայած որ մեր jacobsthal ելքը չփոխվեց:

Սա ակնհայտորեն խնդիր է։

Արագ մի կողմ.

Կրտսեր ծրագրավորողները այս սխալը շատ հաճախ են թույլ տալիս: Ձեր ձևերի համար միշտ չէ, որ պետք է useState: Ես նույնիսկ կառաջարկեմ, որ սովորաբար չանես: Եթե ​​ձեր հայտի ոչ մի մասի կարիք չկա տեսնելու իրական ժամանակի արժեքը, օրինակ՝ ձևը API-ին ներկայացնելիս, փոխարենը պետք է օգտագործեք useRef: Թե ինչպես և ինչու, մենք կանդրադառնանք հետագա հոդվածում:

Այսպիսով, երբ բեմը դրված է և վարագույրները քաշված, ինչպե՞ս ենք մենք լուծելու խնդիրը:

Հիշողություն

Memoization-ը ծրագրավորման տեխնիկա է, որը պահպանում է ֆունկցիայի կանչի արդյունքները, այնպես որ հաջորդ անգամ այդ ֆունկցիան կանչելիս այն պետք չէ վերահաշվարկել ելքը: Փոխարենը, այն կարող է վերադարձնել պահված արդյունքը՝ խնայելով ժամանակի բարդությունը ռեկուրսիվ գործառույթներով։

Սա այն ամենն է, ինչ դուք պետք է իմանաք առայժմ, բայց եթե ցանկանում եք ավելի խորը բացատրություն, ստուգեք այս Memoization in JavaScript հոդվածը GeeksforGeeks-ի կողմից: Եվ այս հոդվածի վերջում մենք կվերափոխենք մեր jacobsthal ֆունկցիան՝ իրականացնելու JavaScript-ի պատշաճ հիշողությունավորում:

useMemo vs. useCallback

Ամփոփելու համար՝ useCallback-ը պահպանում է ֆունկցիայի սահմանումը, այնպես որ այն անհարկի չի վերասահմանում յուրաքանչյուր արտապատկերման վրա: useCallback-ը ստեղծում է ռեֆերենցիալ հավասարություն ֆունկցիայի ատյանների միջև արտապատկերումներով:

Նմանապես, useMemo-ը պահում է ֆունկցիայի կանչի արդյունքը, այնպես որ այն անհարկի վերահաշվարկ չի կատարվում յուրաքանչյուր արտապատկերման ժամանակ: useMemo ստեղծում է ռեֆերենցիալ հավասարություն արժեքի օրինակների միջև արտապատկերումների միջև:

Դուք արդեն կարող եք տեսնել, թե ինչպես է սա օգտակար և ուղղակիորեն տանում դեպի useMemo-ի հիմնական նպատակը: Մի խոսքով, ճիշտ անունով useMemo Hook-ը React-ի ներկառուցված հուշագրման գործիքն է:

useMemo գործողության մեջ

Եկեք մի քանի կոդ գրենք:

Մենք կսկսենք ներմուծել useMemo 'react'-ից:

useMemo Շարահյուսություն

Դուք գուշակեցիք, useMemo-ն ունի նման շարահյուսական կմախք ինչպես useEffect-ին, այնպես էլ useCallback-ին. անանուն հետադարձ զանգ՝ կախվածության զանգվածով:

Ինչպես մեր useCallback օրինակում, մենք ցանկանում ենք քեշավորել այն, ինչ վերադարձվել է այս Կեռիկից: Այսպիսով, մենք կվերագրենք մեր calculation փոփոխականին useMemo վերադարձի արժեքին՝ փաթեթավորելով մեր ֆունկցիայի կանչը անանուն հետ կանչով:

Հիշեք return ձեր ֆունկցիայի կանչի արդյունքը, որպեսզի այն հասանելի լինի useMemo-ով:

Պահելուց հետո մենք ծանոթ նախազգուշացում կնկատենք React-ից: Մեր Կեռիկը բացակայում է կախվածությունից:

Նախքան React-ի նախազգուշացումներին կուրորեն ենթարկվելը, եկեք նախ մտածենք այս կախվածության զանգվածի նպատակի և մեր հավելվածի վրա տարածվող ֆունկցիոնալության մասին:

React Hooks-ով կախվածության զանգվածների նպատակն է ավելի միտումնավոր և հատուկ գործարկել մեր Կեռիկը: Երբ «հետևվող» փոփոխականի արժեքը փոխվում է, Կեռիկը գիտի, որ ժամանակն է անել իր գործը:

Մեր կոնկրետ դեպքում, երբ number-ը փոխվում է, մենք ցանկանում ենք, որ մեր jacobsthal ֆունկցիան վերահաշվարկի արդյունքը:

Այսպիսով, եկեք number ավելացնենք մեր կախվածության զանգվածին:

Այժմ, երբ մենք հիշել ենք մեր գործառույթը, եկեք փորձարկենք այն: Մենք կսկսենք մուտքագրելով 35: Մեր հաշվարկը դեռ ժամանակ է պահանջում, քանի որ մեր jacobsthal ֆունկցիան դեռ հաշվողականորեն թանկ է: Բայց հիմա, երբ մենք մուտքագրում ենք երկրորդ մուտքը, մեր React հավելվածը կրկին արագ և արձագանքող է: Այն այլևս չի վերահաշվարկում մեր jacobsthal արտադրանքը, քանի որ number-ը չի փոխվել:

Եզրակացություն (տեսակի)

Քանի որ մենք հիշել ենք մեր գործառույթի արդյունքները, մենք ստեղծել ենք ռեֆերենցիալ հավասարություն և վերացրել ենք ցանկացած ավելորդ արտապատկերում՝ մեր React հավելվածը դարձնելով ավելի արդյունավետ։

Եթե ​​դուք եկել եք այստեղ միայն React-ի համար, շատ շնորհակալություն կարդալու համար և հետևեք useRef հոդվածին:

Բայց ի՞նչ անել մեր հաշվողականորեն թանկ jacobsthal ֆունկցիայի հետ: Վերափոխելու ժամանակը.

Մենք սկսում ենք previousValues պարամետր ստեղծելով դատարկ զանգվածի լռելյայն արժեքով: Սա կլինի մեր քեշը, որը մենք հետագայում կփոխանցենք մեր ռեկուրսիվ հաջորդականությանը: Դա անելը կխնայի մեր ռեկուրսիվ հաջորդականությունը արտաժամյա աշխատանքից:

Հաջորդը, մեր կոդի բլոկի ներսում, մենք կստեղծենք արդյունքների փոփոխական: Մենք հետագայում կվերահանձնենք արժեքը, ուստի պետք է օգտագործենք մեր let հիմնաբառը:

Մեր հաշվարկներն ուղղակիորեն վերադարձնելու փոխարեն՝ մենք հստակորեն կփաթաթենք մեր ռեկուրսիվ հաջորդականությունը else բլոկի մեջ և մեր return տարբերակները կհատկացնենք resultին:

Այժմ, երբ մեր պայմանականները գնահատեցին և արժեք նշանակեցին result-ին, մենք սահմանեցինք previousValues n ինդեքսը, որը հավասար է մեր ընթացիկ արդյունքին, այնուհետև վերադարձնում ենք result՝ այդպիսով քեշավորելով այս արժեքը և այն հասանելի դարձնելով որպես return:

Հաջորդը, առաջին բանը, որ պետք է անի մեր գործառույթը, ստուգել է՝ արդյոք previousValues n ինդեքսում գոյություն ունի: Եթե ​​դա տեղի ունենա, մենք return այն:

Ի վերջո, մենք կփոխանցենք previousValues-ը որպես փաստարկ մեր ռեկուրսիվ հաջորդականությանը:

Եզրակացություններ (այս անգամ իրականում)

Վայ: Այժմ մենք կարող ենք փորձարկել մեր նոր (և մանրակրկիտ) հիշվող բաղադրիչը: Կրկին փորձեք 35: Բավական արագ, հա՞: Այնքան արագ, իրականում, որ եթե մենք մուտքագրենք 1026, այն դեռ արձագանքում է: Նույնիսկ «Infinity» հաշվարկը չի խափանում մեր հավելվածը: Եվ այո, useMemo-ը դեռ անում է իր գործը:

Մեր մյուս մուտքագրում ուշացում չկա:

Եթե ​​ցանկանում եք ավելի խորը սուզվել useMemo-ի միջոցով, կարող եք ավելին իմանալ React-ի պաշտոնական փաստաթղթերից:

Ես միշտ փնտրում եմ նոր ընկերներ և գործընկերներ: Եթե ​​այս հոդվածը ձեզ օգտակար է համարել և ցանկանում եք միանալ, կարող եք գտնել ինձ համացանցում իմ ցանկացած տներում:

GitHub | Թվիթեր | LinkedIn | Կայք

Ռեսուրսներ