Sunrabbit

[React Hook] useState

สร้าง: 2024-03-14

สร้าง: 2024-03-14 01:53

แปลกๆ นะที่ React ชอบใช้คำว่า use นำหน้า

useServer, useCallback, useState, useMemo และอื่นๆ

แม้แต่ Custom Hook ก็ใช้ use นำหน้าหมด

มันเริ่มมาจากไหนกันนะ


useState เป็น Hook ที่มีชื่อเสียงมาก

ใช้สำหรับเก็บค่าสถานะ และเมื่อค่าสถานะเปลี่ยนแปลง ก็จะทำการ Render ใหม่อีกครั้ง ง่ายมากเลย

เป็นตัวอย่างที่ทุกคนรู้จักกันดี


เมื่อค่าสถานะเปลี่ยนแปลงแล้ว ทำการ Render ใหม่ Scope ไหนบ้าง?

แค่ p tag หรือว่ารวมถึง button tag ด้วย?


คำตอบคือ องค์ประกอบ (Component) ExampleComponent ทั้งหมดที่เรียกใช้ useState

แม้ว่าจะทำการ Render ExampleComponent ใหม่

แต่ก็ใช้ Virtual DOM ในการเปรียบเทียบค่า และแก้ไข DOM ในส่วนที่เปลี่ยนแปลงเท่านั้น


useState ถูกเรียกใช้ทุกครั้งที่ Render ใหม่ แล้วค่าจะคงอยู่ได้อย่างไร?

คำตอบอยู่ที่โครงสร้างของ useState

นี่คือโค้ดจริงของ useState ใน React


ดึง dispatcher จาก Global Object แล้วส่ง useState ไป

แค่นี้ยังไม่เข้าใจโครงสร้าง


ถ้าขุดลึกลงไปอีก จะเจอโค้ดแบบนี้

ดึง hook มาแล้วกำหนดฟังก์ชัน set ให้กับ queue ที่อยู่ใน hook โดยตรงผ่าน bind

(bind จะทำการผูก this ของฟังก์ชันเดิม และใส่ค่าที่เหลือเป็นค่าพารามิเตอร์ของฟังก์ชันนั้น จากนั้นจะคืนค่าฟังก์ชันใหม่ที่มี this ผูกไว้แล้ว)


แค่นี้ยังไม่สามารถหาเหตุผลได้

ลองขุดต่อ


เราสามารถเห็นได้ว่ามีการกำหนดค่า init ทุกครั้ง ซึ่งมันไม่สามารถอธิบายได้ว่าทำไม state ถึงคงอยู่ได้

ลองขุดต่อดูดีกว่า hook ดูมีพิรุธ

currentlyRenderingFiber และ workInProgressHook เป็นตัวแปร Global

ใช้การกำหนดค่าจากขวาไปซ้ายในการสร้าง Linked List


ดังนั้น เราจึงคาดว่าโครงสร้างของ hook จะเป็นแบบนี้

เหมือนกับการเพิ่มค่าไปเรื่อยๆ ที่หัวของ Linked List


แต่ก็ยังอธิบายไม่ได้ เลยลองดูการใช้งาน useState อื่นๆ แล้วพบว่า

ไม่ได้เรียกใช้ mountState ทุกครั้ง แต่จะเรียกใช้ updateState และ rerenderState เมื่อมีการ Render ใหม่

ดังนั้น โครงสร้างจึงเป็นเหมือนที่กล่าวมาข้างต้น และมีการเรียกใช้ฟังก์ชันต่างๆ ตามเหตุการณ์

ถ้าอยากดูโค้ดจริง สามารถดูได้ที่ react/packages/react-reconciler/src/ReactFiberHooks.js

ความคิดเห็น0

สร้างไดเร็กทีฟแบบกำหนดเองใน Nuxt.jsบทความนี้จะอธิบายวิธีการสร้างไดเร็กทีฟการเลื่อนแบบกำหนดเองใน Nuxt.js ครอบคลุมวิธีการใช้ฟังก์ชัน Hook เช่น bind, inserted, update, componentUpdated, unbind และวิธีการลงทะเบียนปลั๊กอิน Nuxt
뚠뚠멍의 생각들
뚠뚠멍의 생각들
뚠뚠멍의 생각들
뚠뚠멍의 생각들

September 28, 2024

[สำหรับผู้ไม่ใช่ผู้เชี่ยวชาญ ด้านการพัฒนาซอฟต์แวร์ เพื่อความอยู่รอด] 14. สรุปเนื้อหาสัมภาษณ์ทางเทคนิคที่ผู้พัฒนาซอฟต์แวร์มือใหม่ถามบ่อยสรุปคำถามทางเทคนิคที่มักถามในการสัมภาษณ์งานผู้พัฒนาซอฟต์แวร์มือใหม่ (พื้นที่หน่วยความจำ โครงสร้างข้อมูล ฐานข้อมูล ฯลฯ) หวังว่าจะเป็นประโยชน์ในการเตรียมตัวสัมภาษณ์งานด้านการพัฒนา
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자

April 3, 2024

[Effective Java] รายการที่ 6: หลีกเลี่ยงการสร้างออบเจ็กต์ที่ไม่จำเป็นการสร้างออบเจ็กต์ที่ไม่จำเป็นนั้นนำไปสู่การสิ้นเปลืองหน่วยความจำ ดังนั้น สำหรับออบเจ็กต์ เช่น สตริง หรือบูลีน ควรใช้ลิเทอรัลหรือเมธอดจากโรงงานแบบคงที่แทน
제이온
제이온
제이온
제이온

April 28, 2024

React - kakao is not defined แก้ไขปัญหานี้อย่างไรดีบทความนี้จะแนะนำวิธีแก้ไขปัญหา 'kakao is not defined' เมื่อใช้ Kakao Map API ใน React คุณสามารถแก้ไขปัญหาได้โดยการประกาศวัตถุ kakao นอกส่วนประกอบ หรือใช้ Custom Hook
뚠뚠멍의 생각들
뚠뚠멍의 생각들
뚠뚠멍의 생각들
뚠뚠멍의 생각들

September 2, 2024

วิธีแคชการตอบสนอง API + การแคชหน้าเว็บบทความนี้แนะนำวิธีการแคชหน้าเว็บและการตอบสนอง API การแคชหลายวิธีโดยใช้พื้นที่จัดเก็บของเบราว์เซอร์, Axios interceptor, เฟรมเวิร์ก Nuxt, Nginx และอื่นๆ พร้อมคำอธิบายข้อดีข้อเสียของการแคชฝั่งเซิร์ฟเวอร์
뚠뚠멍의 생각들
뚠뚠멍의 생각들
뚠뚠멍의 생각들
뚠뚠멍의 생각들

September 29, 2024

เกี่ยวกับการโหลดทรัพยากรของเบราว์เซอร์บทความนี้จะอธิบายวิธีการใช้แอตทริบิวต์ต่างๆ เช่น JavaScript (async, defer), CSS (preload, media), รูปภาพ (loading="lazy", srcset, sizes) และอื่นๆ (prefetch, preconnect, dns-prefetch) เพื่อเพิ่มประสิทธิภาพความเร็วในการโหลดเว็บเพจ
뚠뚠멍의 생각들
뚠뚠멍의 생각들
뚠뚠멍의 생각들
뚠뚠멍의 생각들

October 1, 2024