React 101 (Part 2)
สวัสดีครับ นี่ก็เป็นบทความที่ 2 แล้วนะครับของซีรี่ย์นี้ บทความนี้จะเป็นคิวของ useEffect กันต่อเลย
สำหรับคนที่ยังไม่ได้อ่าน useState ของ part ที่แล้ว คลิกที่นี่ ถ้าพร้อมแล้วเรามาเริ่มกันเลยครับ
useEffect คืออะไร?
useEffect คือ hook ที่ดำเนินการตาม side effects ต่างๆ (life cycle) ของ React จะอธิบายได้ง่ายๆ ตามภาพข้างล่าง
Life cycle ของ React จะมีช่วงชีวิตดังต่อไปนี้ พร้อมคำอธิบายแต่ละช่วงเวลา
- Initialization // ตอนเริ่ม render component
- Mounting // ตอน component render เสร็จ
- Updation // ตอนค่า State มีการอัพเดท
- Unmonting // ตอน destroy component หรือ ออกจากหน้า component นั้นๆ
มาเริ่มเขียนโค้ดกันเลยดีกว่า
ตามภาพ จังหวะ initialization ผมบอก component นี้ให้ set initial state เป็น count มีค่า = 0 และพอตอนที่ component mount เสร็จแล้วให้มีค่าเท่ากับ 1
จริงๆแล้วเจ้าตัว useEffect แบบนี้คือจะทำทุกๆครั้งเมื่อ state มีการอัพเดท หรือ component mount เสร็จ
แล้วถ้าผมอยากจะลองอัพเดทค่า state ดูล่ะ แล้วมาดูกันว่าจะเกิดอะไรขึ้น
ใน log จะเห็นว่าค่า count มีค่าเท่ากับ 2 แล้ว แล้วมันก็มีค่ากลับมาเป็น 1 อีก เพราะว่า ใน useEffect เราเขียนบอกว่า ทุกๆครั้งที่ state มีการอัพเดท value ให้ทำ set ค่า count ให้เป็น 1 นั้นจึงทำให้ count มีค่ากลับมาเป็น 1 อีกครั้ง
และจะทำยังไงล่ะ ถ้าหากต้องการให้ useEffect ทำแค่ครั้งเดียวหลังจาก component mount เสร็จ… ง่ายๆเลยครับ แค่เพิ่ม dependency array ต่อท้าย useEffect
สมมุติว่าผมแค่อยากจะให้ set ค่า count แสดงข้อความบางอย่างครั้งเดียวต่อน component mount เสร็จแค่ครั้งเดียวแล้วไม่อยากให้ทำอะไรอีก
พอผมใส่ dependency array เปล่าๆ เข้าไปแล้ว useEffect ตัวแรกจะทำ set count เป็น 1 และ แสดง log แค่ครั้งเดียว แล้วจะไม่ทำอะไรอีกเลย มาลองกดปุ่ม add count กันดีกว่า
พอผมกด add count useEffect ที่เป็นตัว updating จะทำแค่ตัวเดียว เย้.. setCount ทำแค่ครั้งเดียวแล้ว
ทีนี้ลองมาเพิ่มตัว state อีกหนึ่งตัวกันดีกว่า
จากในรูปผมเพิ่ม count มาอีกตัว แล้วทุกๆครั้งที่ผมกดอัพเดท state ตัวใดตัวนึง useEffect ที่เป็นตัว updating จะแสดงข้อความของ state ทั้ง 2 ตัวออกมาเลย
แล้วจะทำยังไงดีล่ะ ผมอยากให้แสดงแค่ค่าตัวที่ผมอัพเดทเท่านั้น…
เราแค่ เพิ่ม dependency array แบบตัว useEffect ข้างบนเลย เพียงแต่เพิ่มตัวที่เราจะบอก useEffect นั้นว่าจะทำก็ต่อเมื่อมีค่าค่านี้มีการอัพเดทเท่านั้น
งั้นทีนี้ผมลองแยก useEffect และจะบอกแต่ละตัวว่าจะให้ทำเฉพาะค่า state ตัวนั้นๆอัพเดทเท่านั้น ค่อยให้มันทำตามรูปด้านล่าง
ทีนี้พอผมกด add count แต่ละตัว useEffect มันก็จะทำตามค่า state ที่มันได้รับมอบหมายว่าให้ทำเฉพาะค่า state นั้นๆมีการเปลี่ยนแปลง (ในรูปผมเปลี่ยนคำว่า count เป็นดอกไม้ จะได้เห็นชัดๆ)
ต่อมาเป็น life cycle ลำดับสุดท้ายนั้นก็คือ unmounting syntax จะเป็นแบบนี้
คือเราจะเพิ่ม return function เอาไว้ท้ายสุดของ useEffect
จากโค้ด ผมจะทำการแสดง component ด้วยเงื่อนไขของตัว showComponent ถ้ามันค่าเป็นอะไรก็แสดง component ตัวนั้น และจะเห็น useEffect ของแต่ละ component ผมเขียนให้มันว่าถ้า unmount แล้วแสดงข้อความก่อนที่มันจะโดน unmount ด้วย
พอผมกดให้แสดง component 2 เราจะเห็น log ว่ามันแสดงข้อความจาก component 1 ที่มีการทำเมื่อ component 1 โดน unmount
พอกดสลับไปมา useEffect ก็จะแสดงข้อความเมื่อมันได้ทำการ unmount…
use case ของตัว useEffect unmount นี้ ที่ผมคิดออกก็น่าจะเป็นตอนที่ สมมุติผมใช้ component นี่ร่วมกับ redux พอแสดง component นี้แล้วอยากให้ set ค่า redux ไปด้วยที่ใช้เฉพาะใน component นี้ อารมณ์ประมาณ set ค่าใน state แต่ไปใช้ใน redux พอเราใช้ redux set ค่าเสร็จแล้ว เรากำลังจะ unmount จาก component นี้ ก่อนจะ unmount ผมก็จะเขียนว่าให้ clear ค่า redux ที่ผมใช้เฉพาะ component นี้ออก เพื่อที่จะ performace เพราะค่า redux ที่ใช้สำหรับ component นี้จะใช้แค่ที่นี่ พอไป component อื่น หรือ ไป route อื่นๆ ไม่มีความจำเป็นที่จำต้องจำค่านี้ ให้มัน clear ค่าออกไปด้วย เมื่อมัน unmount ประมาณนี้ครับ
- useState ✅ ลิงค์
- useEffect ✅
- useCallback // Coming soon…
- useMemo // Coming soon…
- useContext // Coming soon…
- Custom hook // Coming soon…
จบไปอีกหนึ่งบทเรียนแล้วครับสำหรับ useEffect เป็นยังไงกันบ้าง งงกันบ้างหรือเปล่า555
ถ้าหากผิดพลาดประการใด ขออภัยไว้ ณ ที่นี้ด้วยนะครับ ขอบคุณที่เข้ามาอ่านกันครับ 🙏🙇♂️
Ref