React-ის useCallback პროდუქტიულობის ოპტიმიზაციის ჰუკი
ამ გაკვეთილში ჩვენ განვიხილავთ შემდეგ
პროდუქტიულობის ოპტიმიზაციის ჰუკს
useCallback.
ჰუკი useCallback მსგავსია API useMemo-ის,
განსხვავება ისაა, რომ პირველი
კეშავს მნიშვნელობას ეკრანის გადახატვის მომენტებს შორის,
ხოლო მეორე - კოლბექს.
ეს საშუალებას გვაძლევს არ ხელახლა გავუშვათ რესურსისმომხმარებელი
ფუნქციები, როცა ეს არ არის საჭირო და შეიძლება
გამოყენებულ იქნას
ფუნქციის გადაცემის
შემთხვევაში შვილ კომპონენტებში.
მოდით, უფრო დეტალურად გავერკვიოთ მაგალითზე.
პირველ რიგში, შევქმნათ კომპონენტი App
და მოვაწყოთ მასში სთეითი num:
const [num, setNum] = useState(0);
მოდით გვქონდეს ღილაკი, რომელზე დაწკაპუნებითაც
num იზრდება
1-ით, და აბზაცი, სადაც ჩვენ
გამოვსახავთ მნიშვნელობას num:
return (
<div>
<button onClick={() => setNum(num + 1)}>დაწკაპუნება</button>
<p>დაწკაპუნებები: {num}</p>
</div>
);
ახლა კი, დავუშვათ, რომ ჩვენ
App-ში გამოისახება კიდევ რაღაც სია
ელემენტებით, რომელსაც ჩვენ შევავსებთ
სხვა ღილაკზე დაწკაპუნებით. ამ სიის
ელემენტების შესანახად ჩვენ მოვაწყობთ
სთეითს items:
const [items, setItems] = useState([]);
შემდეგ კი დავწერთ ფუნქციას addItem
მათი დასამატებლად:
function addItem() {
setItems([...items, 'ახალი ელემენტი']);
}
ახლა მოდით დავწეროთ კოდი სიის ელემენტების გამოსახვისთვის
და გამოვყოთ ის შვილ კომპონენტში Items, რომელიც პროფების
სახით მიიღებს ელემენტების მასივს
და ფუნქციას მათი დასამატებლად. არ დაგვავიწყდეს
კონსოლში გამოტანის დამატება, რომ დავინახოთ
როდის გადაიხატება ჩვენი Items:
function Items({ items, addItem }) {
const result = items.map((item, index) => {
return <p key={index}>{item}</p>;
});
console.log('Items გადაიხატა');
return (
<div>
<h3>ჩვენი ელემენტები</h3>
{result}
<button onClick={addItem}>ელემენტის დამატება</button>
</div>
);
}
export default Items;
მოვათავსოთ Items კომპონენტის
App ბოლოში და მივცეთ მას მასივი
items და ფუნქცია ელემენტების დასამატებლად
addItem:
return (
<>
<div>
<button onClick={() => setNum(num + 1)}>დაწკაპუნება</button>
<p>დაწკაპუნებები: {num}</p>
<br />
</div>
<Items items={items} addItem={addItem} />
</>
);
ახლა კი დავაწკაპუნოთ ღილაკებს
და დავრწმუნდეთ, რომ num იზრდება და
ახალი ელემენტები ემატება სიას.
ხოლო კონსოლის გახსნით, ჩვენ დავინახავთ, რომ
ჩვენი სია გადაიხატება ყოველ
ჯერზე, მაშინაც კი, თუ ჩვენ ვაწკაპუნებთ იმ ღილაკს,
რომელიც ზრდის num-ს.
თუ ჩვენ გვაქვს პატარა სია, მაშინ ყველაფერი
კარგადაა, მაგრამ რა მოხდება, თუ ვივარაუდებთ, რომ ის
იქნება მოცულობითი და იქ ბევრი რამეა?
პრობლემა არ არის - იტყვით თქვენ, რადგან წინა
გაკვეთილზე ჩვენ განვიხილეთ API memo,
რომ თავი ავარიდოთ კომპონენტის არასაჭირო გადახატვებს.
მოდით, ჩავსვათ ჩვენი კომპონენტი
Items memo-ში და მორჩა.
სხვათა შორის, ეს შეიძლება გაკეთდეს პირდაპირ
ექსპორტის დროს Items:
export default memo(Items);
არ დაგვავიწყდეს memo-ის იმპორტი:
import { memo } from 'react';
ახლა კი გავხსნათ კონსოლი და დავაწკაპუნოთ
ღილაკებს. ყველა ძალისხმევა უშედეგოდ! ჩვენ
მემოიზირებული გვაქვს კომპონენტი, მაგრამ ღილაკზე 'დაწკაპუნება' დაწკაპუნებისას კომპონენტი
Items მაინც
გადაიხატება ყოველ ჯერზე.
საქმე ისაა, რომ როდესაც მშობელი
კომპონენტი გადაიხატება, მისი ფუნქციები
ხელახლა იქმნება - ეს ეხება ჩვენს
ფუნქციას addItem-საც, რომელსაც ჩვენ ვაწვდით
Items-ს.
სწორედ ამ მომენტში დაგვეხმარება ჰუკი
useCallback. მოდით გამოვიყენოთ ის.
პირველ რიგში, იმპორტი გავაკეთოთ
App-ში:
import { useCallback } from 'react';
შემდეგ გადავაკეთოთ ფუნქციის
addItem უბრალო დეკლარაცია
Function Expression-ად, მივუთითოთ როგორც
პირველი პარამეტრი useCallback-ისთვის
ჩვენი ფუნქცია კოლბექის სახით. მეორე
პარამეტრად კვადრატულ ფრჩხილებში მივუთითოთ
დამოკიდებულებები - ყველა რეაქტიული ცვლადი,
რომელიც მონაწილეობს ფუნქციაში, ჩვენს შემთხვევაში
ეს არის მასივი items:
const addItem = useCallback(() => {
setItems(() => [...items, 'ახალი ელემენტი']);
}, [items]);
მზადაა! ამით ჩვენ დავკეშეთ
ფუნქცია. კიდევ ერთხელ დავაწკაპუნოთ ღილაკებს და
ვნახოთ, რომ ახლა ღილაკზე 'დაწკაპუნება' დაწკაპუნებისას ჩვენი შვილი კომპონენტი აღარ
გადაიხატება.
შექმენით კომპონენტი App, მოათავსეთ
მასში აბზაცი ტექსტით. მოაწყობეთ
სთეითი საწყისი მნიშვნელობით 'ტექსტი'
და გამოსახეთ ის აბზაცში. მოდით, აბზაცზე დაწკაპუნებისას
მის ტექსტის ბოლოს
დაემატოს ძახილის ნიშანი.
შექმენით შვილი კომპონენტი Products,
სადაც თქვენ გექნებათ ღილაკი ახალი
პროდუქტის დასამატებლად. მოათავსეთ ის App-ში.
მშობელ კომპონენტში შექმენით სთეითი
პროდუქტების მასივით და ფუნქცია ახალი
პროდუქტის დასამატებლად. გადაეცით ისინი
პროფების სახით შვილს, გამოსახეთ მასში
გადაცემული მასივი სიის ul სახით.
Products-ში გამოიტანეთ კონსოლში ტექსტი
'products გადაიხატა'.
ჩაახვიეთ Products memo-ში.
დააწკაპუნეთ აბზაცს და ღილაკს. დარწმუნდით,
რომ აბზაცზე დაწკაპუნებისას შვილი კომპონენტი
მაინც გადაიხატება.
დაკეშეთ ფუნქცია პროდუქტების დასამატებლად,
ჩაახვიეთ ის ჰუკ useCallback-ში.
დააწკაპუნეთ აბზაცს და ღილაკს. დარწმუნდეთ,
რომ აბზაცზე დაწკაპუნებისას, შვილი კომპონენტი
აღარ გადაიხატება.