การใช้งานฟังก์ชัน useCallback เพื่อช่วยลดการ re-renders ของ components ใน React

วันนี้เราจะมาทำความรู้จะกับ useCallback ซึ่งเป็น React Hook ที่จะช่วยแคช (cache) ฟังก์ชัน ระหว่างการ re-renders components แล้วทำไมเราต้อง cache ฟังก์ชันด้วยล่ะ อย่างที่เรารู้กัน ใน javascript นั้น function () {} และ () => {} จะเป็นการสร้างฟังก์ชันใหม่ คล้ายๆ กับ {} ที่เป็นการสร้าง object ใหม่ ถึงแม้ว่าจะมีหน้าตาเหมือนเดิมเป๊ะๆ ก็ตาม

ถ้า props ที่เราส่งไปยัง components ไม่มีการเปลี่ยนแปลง เราสามารถใช้ React.memo เพื่อ skip re-render components นั้นๆ ได้ แน่นอนว่าบาง props ที่เราส่งไปนั้นก็เป็นฟังก์ชัน และเป็นจุดที่เราจะนำ useCallback เข้ามาช่วย cache ฟังก์ชันเหล่านั้น

const ProductPage = ({ productId, theme }) => {
  const handleSubmit = useCallback((details) => {
    post("/subscribe/" + productId, {
      details
    });
  }, [productId]);
  return (
    <Container theme={theme}>
      <SubscribeForm handleSubmit={handleSubmit} />;
    </Container>
  );
};

const SubscribeForm = React.memo(({ handleSubmit }) => {
  return ...;
});

จากตัวอย่างถ้า productId ที่เป็น dependencies ของ useCallback ไม่มีการเปลี่ยนแปลงค่า ฟังก์ชัน useCallback ก็จะ return ใช้ฟังก์ชันที่ cache ไว้ แต่ถ้ามีการเปลี่ยน productId ค่า ฟังก์ชัน useCallback ก็จะอัพเดท cache และ return handleSubmit ที่เป็นของ productId ใหม่มาให้อีกครั้ง

จากตรงนี้ถ้าหาก SubscribeForm เป็น component ที่ต้องใช้เวลาในการ render นาน เราจะเห็นว่าแอพฯ ของเรา มันหน่วงๆ พอนำ useCallback เข้ามาช่วยในจุดนี้ ก็จะทำให้ไม่ต้อง re-render SubscribeForm ทำให้การใช้งานดูไม่หน่วงหรือกระตุก