Published on

เรียนรู้ - useCallback

เรียนรู้ - useCallback
เรียนรู้ - useCallback

อันยองงง บทความวันนี้อาจจะสั้นนิดนึงเน้อครับ ส่วนนึงเพราะรู้สึกเหนื่อย ๆ ด้วยแต่ก็อยากเขียนบทความให้ได้ทุกสัปดาห์ ถึงแม้ว่าจะหลุดบ้างบางสัปดาห์แล้วก็ตาม ฮ่าาาา

ในสัปดาห์ที่ผ่านมาได้ทำความเข้าใจ useCallback แบบตั้งใจสักที จากที่ผ่าน ๆ มา คือรู้แค่ว่ามันใช้แบบคล้าย ๆ กับ useMemo ประมาณว่า useCallback จะใช้ cache function แต่ useMemo จะใช้ cache ข้อมูล

เรามาทำความเข้าใจกันดีกว่าครับ

useCallback คืออะไร?

useCallback เป็น React Hook อันนึงที่ใช้สำหรับจัดเก็บ cache ของ function ช่วยลดการสร้าง function ใหม่ในการ render ในแต่ละครั้งที่เกิดการ render ซ้ำของ component

จบ. แฮร่! หยอก ๆ จบแบบนี้บทความจะสั้นไปนะครับ

มาดูตัวอย่างกันครับ

App.jsx
import { useState, useCallback } from 'react';

export function App(props) {
  const [count, setCount] = useState(0);

  const handleSetCount = useCallback(() => {
    console.log(count)
    setCount((prev) => prev + 1)
  }, [])

  return (
    <div>
      <div>
        count: {count}
      </div>

      <div>
        <button onClick={handleSetCount}>+</button>
      </div>
    </div>
  );
}

จากตัวอย่างเมื่อเอาไป Run แล้วจะพบว่าเมื่อกดปุ่ม + ถึงแม้ว่า state ของ count ที่ render ในหน้าจอจะเปลี่ยน แต่หากดูใน console ที่เรา console มาจะพบว่าค่า count ที่ เรา console.log ไว้ จะเป็นค่า 0 ตลอด

เนื่องจากครั้งแรกที่ Render component ค่า count เริ่มต้นเป็น 0 ทำให้ handleSetCount ที่เรา cache ไว้ค่า count จึงเป็น 0 ตลอดทุกครั้งที่เรากด

คำถามคือแล้วทำไมใน count ที่ render ถึงค่าเปลี่ยนล่ะ

ต้องบอกแบบนี้ก่อนครับว่าในการ setState ทำได้ 2 แบบคือ set ค่าตรง ๆ หรือไม่ก็ set ผ่านโดยการ pass function

ในตัวอย่างข้างต้นคือเรา set ผ่านการ pass function โดยเอาค่า previous state บวกด้วย 1

ทำให้ค่า count ถูกเปลี่ยน

แต่ count ที่เรา console.log ใน handleSetCount มันเป็นค่า count ครั้งแรก มันจึงเป็นค่า 0 ตลอดทุกครั้งที่เรากดปุ่ม +

เราสามารถกำหนดค่า dependencies ได้ เช่น ถ้าค่า count เปลี่ยนแปลง ให้ cache function ใหม่

ตัวอย่างถ้าหากอยาก cache function ใหม่ทุกครั้ง count เปลี่ยน สามารถกำหนดได้ดังนี้ และสามารถ setCount ตรงๆ ได้

const handleSetCount = useCallback(() => {
  setCount(count + 1)
}, [count])

แต่ถ้าใช้แบบนี้คือเราอาจจะไม่จำเป็นต้องใช้ useCallback ก็ได้ครับ ^^

หากบทความนี้ผิดพลาดประการใด ก็ขออภัยมา ณ​ ที่นี้ด้วยเน้อครับ หรือหากคุณผู้อ่านมีข้อสงสัยตรงส่วนไหนหรืออยากแนะนำส่วนไหนเพิ่มเติม สามารถพิมพ์สอบถามได้ทาง comment ได้เลยเน้อครับ