เมื่อ React บอกว่ามีการ Re-render นั่นหมายถึง 3 สิ่งนี้

เมื่อคุณเรียกใช้ setState React ไม่ได้เพียงแค่ทำอัปเดต DOM เท่านั้น แต่มันจะรัน 3 เฟสที่แยกจากกันตามลำดับ นักพัฒนาส่วนใหญ่มักสับสนในเฟสเหล่านี้ การเข้าใจความแตกต่างจะช่วยให้คุณแก้ไขปัญหาด้านประสิทธิภาพได้

3 เฟสที่เกิดขึ้น:

• Render: React เรียกใช้ฟังก์ชันคอมโพเนนต์ของคุณ • Reconcile: React เปรียบเทียบผลลัพธ์ใหม่กับผลลัพธ์เก่า • Commit: React นำการเปลี่ยนแปลงไปใช้กับ DOM

  1. เฟส Render

React รันฟังก์ชันของคุณ โดยใช้ props ปัจจุบัน ฟังก์ชันจะคืนค่าเป็น JSX ซึ่ง JSX นี้เป็นเพียงรายการของ JavaScript objects เท่านั้น ผู้คนเรียกสิ่งนี้ว่า virtual DOM แต่มันไม่ใช่ DOM จริงๆ มันเป็นเพียงคำอธิบายว่า UI ควรจะมีหน้าตาเป็นอย่างไร ในเฟสนี้จะยังไม่มีอะไรปรากฏบนหน้าจอ เฟสนี้จึงเป็นเรื่องของคณิตศาสตร์และตรรกะล้วนๆ

  1. เฟส Reconcile

React จะถือทั้ง tree เก่าและ tree ใหม่ไว้ แล้วมองหาความแตกต่างระหว่างกัน หากประเภทของ element เปลี่ยนไป React จะแทนที่ tree ทั้งหมด แต่ถ้าเปลี่ยนแค่ props, React จะอัปเดตเฉพาะส่วนนั้น นี่คือจุดที่ keys มีความสำคัญ เพราะ keys ช่วยให้ React จับคู่รายการใน list ด้วย identity แทนที่จะใช้ตำแหน่ง (position) เฟสนี้จะสร้างรายการขั้นตอนที่น้อยที่สุดที่จำเป็นในการอัปเดต DOM

  1. เฟส Commit

React นำรายการการเปลี่ยนแปลงมาจัดการกับ DOM จริง โดยการสร้าง node ใหม่และลบ node เก่าออก นี่คือช่วงที่ผู้ใช้จะเห็นการเปลี่ยนแปลงบนหน้าจอ หลังจากนั้น browser จะทำการ paint หน้าจอ และตามด้วยการรัน useEffect

ความเข้าใจผิดที่พบบ่อย:

• การ re-render ไม่ได้หมายความว่าจะต้องเปลี่ยน DOM เสมอไป หากผลลัพธ์เหมือนเดิม React จะไม่ทำอะไรเลยในเฟส commit • React.memo ช่วยข้ามการเรียกฟังก์ชัน แต่ไม่ได้ข้ามการอัปเดต DOM • Props ไม่ได้เป็นตัวกระตุ้น (trigger) การ re-render โดยตรง แต่การที่ parent ทำการ re-render จะส่งผลให้ child ทำการ re-render ด้วย ส่วนการเปลี่ยนค่า prop นั้นเป็นเพียงผลลัพธ์ที่ตามมา

วิธีแก้ไขปัญหาด้านประสิทธิภาพ:

หากฟังก์ชันของคุณทำงานช้า แสดงว่าคุณมีปัญหาที่เฟส Render ให้ย้ายงานหนักๆ ออกจากฟังก์ชัน หรือใช้ memoization

หาก React ต้องสร้าง list ขนาดใหญ่ใหม่ทั้งหมด แสดงว่าคุณมีปัญหาที่เฟส Reconcile ให้ตรวจสอบการใช้ keys ของคุณ

หากมีการอัปเดต DOM มากเกินไป แสดงว่าคุณมีปัญหาที่เฟส Commit ให้ใช้ virtualization หรือปรับเปลี่ยนโครงสร้างของคุณ

ปัจจุบัน React 19 และ React Compiler ช่วยจัดการงานส่วนใหญ่เหล่านี้ให้คุณแล้ว แต่การเข้าใจเฟสเหล่านี้จะช่วยให้คุณ debug ได้ดีขึ้น

Source: https://dev.to/dip_032d2fe1959e1990ddbb1/when-react-says-re-render-it-actually-means-three-things-11d7