1. Home
  2. react-usecallback-hook

React.useCallback Hook အသုံးပြုပုံ

article image

တချို့တွေက useCallback ကို function တိုင်းမှာ သုံးရမယ်လို့ထင်တတ်ကြပါတယ်။ အဲဒီလို သုံးမယ်ဆိုရင် component ကို နှေးကွေးစေပါတယ်။

ဒီ post မှာ useCallback ကို မှန်မှန်ကန်ကန် ဘယ်လိုအသုံးချရမလဲဆိုတာ ပြောပြချင်ပါတယ်။

၁။ Function equality check

useCallback အကြောင်းမပြောခင် သူကဘာပြဿနာကို ဖြေရှင်းပေးသလဲဆိုတာ အရင်ဆုံးပြောပြချင်ပါတယ်။

Function ကို return ပြန်တဲ့ factory() ဆိုတဲ့ function တစ်ခုရေးကြည့်ရအောင်။

function factory() {
   return (a, b) => a + b;
}
const sum1 = factory();
const sum2 = factory();
sum1(1, 2); // => 3
sum2(1, 2); // => 3
sum1 === sum2; // => false
sum1 === sum1; // => true;

sum1 နှင့် sum2 တွေက factory() function က create လုပ်ထားတဲ့ ကိန်းဂဏန်း (၂) ခု ကိုပေါင်းပေးတဲ့ function တွေဖြစ်ပါတယ်။

JavaScript မှာ function တွေက regular object တွေဖြစ်ပါတယ်။

Function object တစ်ခုက တခြား function တစ်ခုကို return ပြန်လို့ရပါတယ်။ (factory() function က လုပ်သလိုမျိုး)။ ပြီးတော့ အဲဒီ function တစ်ခုနှင့်တစ်ခု နှိုင်းယှဉ်လို့ရပါတယ်။ Object တစ်ခုက လုပ်လို့ရသမျှအကုန်လုံး လုပ်လို့ရပါတယ်။

ဒီနေရာမှာ function sum1 နှင့် sum2 တွေက code တွေတူညီပေမဲ့လည်း သူတို့တွေဟာ မတူညီတဲ့ function object တွေဖြစ်ပါတယ်။ ဒါကြောင့် sum1 === sum2 နှိုင်းယှဉ်ကြည့်တဲ့အခါ false ထွက်လာပါတယ်။

ဒါက Javascript object တွေရဲ့ အလုပ်လုပ်ပုံဖြစ်ပါတယ်။ Object တစ်ခု (function object အပါအဝင်) သူနှင့်သူပဲ နှိုင်းယှဉ်မယ်ဆိုရင် တူညီပါတယ်။

၂။ useCallback ရဲ့ ရည်ရွယ်ချက်

တစ်ခါတရံ code တူပြီး function object မတူတဲ့ function တွေကို React component ထဲမှာ create လုပ်ဖို့လိုအပ်လာတတ်ပါတယ်။

import React from ‘react’;
function MyComponent() {
   // handleClick is re-created on each render
   const handleClick = () => {
     console.log(‘Clicked!’);
   };
// …
};

MyComponent ကို render လုပ်တဲ့အချိန်တိုင်း handleClick() ဟာ မတူညီတဲ့ function object အဖြစ်ရှိနေပါလိမ့်မည်။ Rendering လုပ်တဲ့အချိန်တိုင်း function re-create လုပ်တာက ဘာမှတော့ပြဿနာ မဟုတ်ပါဘူး။ ဒါပေမဲ့လည်း တစ်ချို့ကိစ္စရပ်တွေမှာ render လုပ်တဲ့အချိန်တိုင်း function instance တစ်ခုဟာ re-create မလုပ်ဘဲ ဆက်လက်တည်ရှိနေဖို့ လိုအပ်ပါတယ်။

  1. React.memo() ထဲမှာ function object prop တစ်ခုကို လက်ခံထားတဲ့ functional component တစ်ခုကို wrap လုပ်တဲ့အချိန်
  1. Function object ဟာ hook တွေရဲ့ dependency တစ်ခုအဖြစ်ရှိနေတဲ့အချိန်

ဥပမာ — useEffect(…, [callback])

import React, { useCallback } from ‘react’;
function MyComponent() {
  // handleClick is the same function object
   const handleClick = useCallback(() => {
      console.log(‘Clicked!’);
   }, []);
  // …
};

MyComponent ကို re-render လုပ်တဲ့အချိန်တိုင်း handleClick variable က အသစ်တစ်ခု create ပြန်လုပ်တာမဟုတ်ဘဲ နဂိုရှိသည်အတိုင်း ဆက်လက်တည်ရှိနေပါလိမ့်မည်။

၃။ သုံးသင့်တဲ့နေရာ

ကြီးမားတဲ့ list တစ်ခုကို render လုပ်တဲ့ component တစ်ခု create လုပ်မယ်ဆိုကြပါစို့:

import React from ‘react’;
import useSearch from ‘./fetch-items’;
function MyBigList({ term, onItemClick }) {
   const items = useSearch(term);
   const map = item => <div onClick={onItemClick}>{item}</div>;
   
   return <div>{items.map(map)}</div>;
}
export default React.memo(MyBigList);;

List က ကြီးတဲ့အတွက်ကြောင့် ဘာမှပြောင်းလဲတဲ့အရာမရှိဘဲ re-render လုပ်တာကနေ ကာကွယ်ဖို့အတွက် React.memo() ထဲမှာ ဒီ component ကို wrap လုပ်ထားတာဖြစ်ပါတယ်။

MyBigList component ရဲ့ parent component က item တွေကို click လုပ်တာကို handle လုပ်ဖို့အတွက် function တစ်ခုရှိနေပါတယ်။

import React, { useCallback } from ‘react’;
export default function MyParent({ term }) {
   const onItemClick = useCallback(event => {
      console.log(‘You clicked ‘, event.currentTarget);
   }, [term]);
   return (
      <MyBigList
       term={term}
       onItemClick={onItemClick}
     />
  );
};

onItemClick callback function ကို useCallback() က မှတ်သားထားပါတယ်။ Item တစ်ခုချင်စီအတွက် onItemClick ဆိုတဲ့ prop ကို ပေးထားပေမဲ့လည်း useCallback() က တူညီတဲ့ function object ကို return ပြန်ပေးပါတယ်။

MyParent component ကို re-render လုပ်တဲ့အချိန်မှာ onItemClick function object က အသစ်တစ်ခု create မလုပ်ဘဲနဲ့ တစ်ခုတည်းပဲဆက်လက်တည်ရှိနေပါတယ်။

၄။ မသုံးသင့်တဲ့နေရာ

တခြား ဥပမာတစ်ခု ကြည့်ရအောင်။

import React, { useCallback } from ‘react’;
function MyComponent() {
    const handleClick = useCallback(() => {
    // handle the click event
    }, []);
      return <MyChild onClick={handleClick} />;
   }
function MyChild ({ onClick }) {
    return <button onClick={onClick}>I am a child</button>;
};

useCallback() ကို MyComponent ကို render လုပ်တဲ့အချိန်တိုင်း ခေါ်ပါတယ်။ useCallback() က တူညီတဲ့ function object တွေကို return ပြန်ပေမဲ့လည်း re-render လုပ်တဲ့အချိန်မှာ inline function ကို re-create လုပ်ပါတယ်။

ဒါကြောင့် ဘာမှသက်ရောက်တဲ့အရာမရှိပါဘူး။ Code ကို ပိုရှုပ်ထွေးစေတာကလွဲလို့ပေါ့။

ဒါကြောင့် function re-create လုပ်တဲ့အရာကို ဒီအတိုင်းလက်ခံရမှာဖြစ်ပါတယ်။

import React, { useCallback } from ‘react’;
function MyComponent() {
    const handleClick = () => {
    // handle the click event
    };
    return <MyChild onClick={handleClick} />;
}
function MyChild ({ onClick }) {
    return <button onClick={onClick}>I am a child</button>;;

၅။ အနှစ်ချုပ်

တချို့ ပိုကောင်းအောင်ရေးထားတဲ့ဟာတွေက ပိုမိုရှုပ်ထွေးစေတတ်ပါတယ်။ အစောကြီး Performance ကောင်းအောင်ရေးထားမယ်ဆိုရင် မကောာင်းပါဘူး။ ဘာဖြစ်လို့ဆိုရင် code တွေက ခဏခဏပြောင်းလဲနေမှာ မို့လို့ပါ။

useCallback ကို child component အများကြီးရှိတဲ့ component တွေမှာပဲ အသုံးပြုသင့်ပါတယ်။ Child component အများကြီးမရှိတဲ့ component တွေမှာသုံးမယ်ဆိုရင် Perfomance ကိုကျစေနိုင်ပါတယ်။ Performance ကောင်းအောင်ရေးရင်လည်း အနည်းငယ်ရှုပ်ထွေးမှုတော့ ရှိနေမှာပါ။


Comments

Let me know your opinion

Related Articles

Feedbacks