สรุปการเลือกใช้งาน React 16.4+ component life-cycle methods

Nes Chaiyapon
3 min readOct 11, 2018

--

รูปภาพจากโปรเจ็ค https://github.com/wojtekmaj/react-lifecycle-methods-diagram

ตัว React component เองก็มี life-cycle ของมันอยู่ครับ เราสามารถเข้าไปใช้งาน life-cycle ต่างๆ ได้ด้วยการใช้งาน class component ซึ่งจะมี life-cycle methods ต่างๆ ของ component ให้เราเลือกใช้กันครับ

ความรู้เรื่อง Life cycle methods ของ React component มีประโยชน์อย่างมากต่อการใช้งาน React library เพราะถ้าเรารู้ว่าเมธอดนี้คือเมธอดอะไร จะทำงานตอนไหนของ life cycle เราก็จะสามารถที่จะเลือกใช้เมธอดเหล่านี้เพื่ออัพเดท UI หรือ application state หรือทำงานอย่างอื่นได้

และเนื่องจากตั้งแต่ React เวอร์ชั่น 16.4 ขึ้นไปได้มีการเปลี่ยนแปลง component life-cycle methods ใหม่ ผมจึงทำการสรุป life-cycle methods ต่างๆ ไว้ดังนี้

หากต้องการดูภาพประกอบแบบชัดๆ ก็มีคนทำโปรเจ็คไว้เป็น React lifecycle methods diagram ครับ สามารถเข้าไปดูเพื่อประกอบการอ่านกันได้ครับ

เริ่มจากส่วนของ life cycle methods ที่จะทำงานตอน Mounting component ก่อนนะครับ

constructor(props)

เมธอดนี้เป็นเมธอดที่ถูกเรียกเป็นอันดับแรก เพราะเป็นเมธอดที่จะถูกทำการเรียกเมื่อมีการสร้าง object ขึ้นมาใหม่ ซึ่งเป็นเรื่องพื้นฐานของ programming paradigm แบบ OOP

เวลาใช้งานเมธอดนี้ เราควรเรียก super(props) ไว้ภายในเมธอด ด้วย เพราะ super(props) จะไปเรียก constructor ของคลาสแม่ทำให้เราสามารถใช้งาน this.props ใน component ได้ ถ้าเราไม่เรียก super(props) this.props ก็จะมีค่าเป็น undefined แต่ยกเว้นใน es7 ขึ้นไป ที่เราสามารถกำหนด state property เริ่มต้นโดยไม่ต้องใช้ constructor ได้

สิ่งที่ทำได้

  • กำหนดค่าเริ่มต้นของ state
  • กำหนดค่าเริ่มต้นของ properties ใน class
  • ใช้ในการ binding event handler method ให้กับ instance

สิ่งที่ไม่ควรทำ

  • ไม่ควรทำ side effect ต่างๆ เช่นการ fetch data จาก api

static getDerivedStateFromProps(nextProps, prevState)

เมธอดนี้เป็นเมธอดที่จะถูกเรียกต่อจาก constructor method ในขั้นตอน mounting component โดยเมธอดนี้จะมีความสามารถในการนำค่าของ props ไปเก็บไว้ใน state มักจะถูกใช้ในกรณีที่ค่าใน state ต้องมีการเปลี่ยนแปลงตาม props ที่รับเข้ามา โดย object ที่ถูกรีเทิร์นไปจากเมธอดนี้ ก็จะไป merge กับค่าใน state ทำให้ค่าใน state เปลี่ยนแปลง และนอกจากนี้ยังเหมาะสำหรับ initial ค่าใน state ที่จะมาจาก props โดยไม่ต้องไปทำใน constructor เพราะเมธอดนี้จะถูกเรียกต่อจาก constructor

แต่มีข้อยกเว้นสำหรับเมธอดนี้ก็คือ เมธอดนี้จะไม่สามารถเข้าถึงตัวแปร this ได้เพราะเป็น static method เหตุที่เมธอดนี้ถูกเขียนเป็น static method ก็เพราะป้องกันการนำไปใช้ในทางที่ผิด เช่น การเรียกใช้ this.setState เซ็ตค่าของ state ในเมธอดนี้ก็จะไม่สามารถทำได้

สิ่งที่ทำได้

  • นำค่าของ props ไปเก็บไว้ใน state

สิ่งที่ไม่ควรทำ

  • ไม่ควรทำ side effect ต่างๆ เช่นการ fetch data จาก api

render()

เมธอดนี้เป็นเมธอดเดียว ที่จะต้องมีทุกครั้งเวลาสร้าง class component เป็น เมธอดที่ใช้สำหรับรีเทิร์น react element เพื่อไปแสดงผลบนหน้าจอ นอกจากรีเทิร์น element แล้ว เมธอดนี้ก็สามารถที่จะรีเทิร์น arrays, string, number, null, booleans ได้เช่นกัน

เมื่อเมธอดนี้ทำงาน children component ที่อยู่ภายใต้ component นี้ก็จะถูก render ไปด้วย

สิ่งที่ทำได้

  • รีเทิร์นสิ่งที่จะนำไปแสดงผลบนหน้าจอ

สิ่งที่ไม่ควรทำ

  • ไม่ควรทำการเรียกใช้ this.setState ในเมธอดนี้ เพราะจำทำให้เกิดการ render ตัวเองซ้ำๆ
  • ไม่ควรทำ side effect ต่างๆ เช่นการ fetch data จาก api

componentDidMount()

เมธอดนี้จะถูกเรียกเมื่อทำการ mouth component เสร็จสิ้นแล้ว และเมธอดนี้จะถูกเรียกครั้งเดียว ตอน mouth component เสร็จสิ้นเท่านั้น จึงเหมาะสำหรับทำการ fetch data จาก api มาแสดงผล หรือทำการ subscriptions สิ่งต่างๆ

สิ่งที่ทำได้

  • fetch data จาก api
  • subscriptions สิ่งต่างๆ

สิ่งที่ไม่ควรทำ

หากต้องการเรียก this.setState ในเมธอดนี้ก็สามารถทำได้ แต่จะทำให้เกิดการ rerender อีกครั้งนึง แต่ user มองไม่เห็น เพราะมันจะเกิดก่อน browser อัพเดท screen เสร็จ ควรใช้ด้วยความระมัดระวังเพราะอาจเกิด performance issue ขึ้นมาได้

ถัดมาเป็นส่วนของ life cycle methods ที่จะทำงานเมื่อมีการ Updating component ครับ

static getDerivedStateFromProps(nextProps, prevState)

เมธอดนี้เป็นเมธอดเดิมที่เรากล่าวถึงกันไปแล้วครั้งหนึ่ง ในส่วนของ life-cycle ที่จะทำงานตอน mounting component แต่เมธอดนี้จะถูกทำการเรียกอีกครั้งเมื่อมีการ updating component เช่น เมื่อ props เปลี่ยน, มีการเรียก this.setState, มีการเรียก this.forceUpdate

หน้าที่ของมันก็ยังคงเหมือนเดิมคือการนำค่าจาก props ไปเก็บไว้ใน state แต่ที่มันถูกเรียกเมื่อ props เปลี่ยนอีกครั้ง ก็เพื่อที่จะทำให้เราสามารถเปลี่ยนค่าใน state ของ component ตาม props ที่เปลี่ยนแปลงได้

shouldComponentUpdate(nextProps, nextState)

เมธอดนี้เป็นเมธอดที่จะถูกเรียกก่อน render method ในช่วงของ life-cycle ที่จะทำงานตอน updating component มันมีความสามารถในการตัดสินใจได้ว่าจะทำการเรียก render method ที่ปกติจะถูกเรียกเป็นอันดับถัดไปหรือไม่ เพื่อแก้ไขปัญหา performance เพราะบางครั้งเวลาที่ props หรือ state บางตัวเปลี่ยน เราก็ไม่ได้ต้องการให้ component นี้ rerender ตัวเองอีกครั้ง

การตัดสินใจว่าจะ render อีกครั้งหรือไม่ทำได้โดย รีเทิร์นค่า booleans ออกไปจากเมธอดนี้ โดยหากรีเทิร์น true จะทำให้ render method ถูกเรียก หาก รีเทิร์น false ก็จะทำให้ render method ไม่ถูกเรียก

สิ่งที่ทำได้

  • ใช้ตัดสินใจว่าจะ render หรือไม่ถ้า state หรือ props ตัวนี้เปลี่ยน เพื่อแก้ไขปัญหา performance ที่เกิดจากการ rerender ตัวเองหลายครั้ง

สิ่งที่ไม่ควรทำ

  • ไม่ควรเรียก this.setState ในนี้เพราะจะทำให้เกิดการ render ตัวเองซ้ำๆ
  • ไม่ควรทำ side effect ต่างๆ เช่นการ fetch data จาก api ใน method นี้

render()

เมธอดนี้ก็จะถูกเรียกอีกครั้งเมื่อมีการอัพเดทเกิดขึ้นและ shouldComponentUpdate method รีเทิร์น true ซึ่งปกติถ้าไม่ได้ใช้ shouldComponentUpdate method เมธอดนี้ก็จะถูกเรียกตลอดเมื่อมีการอัพเดทเกิดขึ้นโดยมันยังคงทำหน้าที่เหมือนเดิมทุกประการ

getSnapshotBeforeUpdate(prevProps, prevState)

เมธอดนี้จะถูกเรียกหลังจาก render แต่ก่อน component อัพเดทตัวเองเสร็จ ในเมธอดนี้เราสามารถเข้าถึงค่าของ DOM ก่อนที่ component จะอัพเดทเสร็จได้ (สามารถเข้าถึงค่าของ DOM ได้ผ่านทาง ref)

มักจะใช้ในการอ่านค่าของ current DOM เวลาที่มี props หรือ state เปลี่ยน เพื่อนำไปใช้คำนวณต่อใน componentDidUpdate method ในตอนที่ component อัพเดทตัวเองเสร็จแล้ว การใช้เมธอดนี้เราจะต้องรีเทิร์นค่าออกไปจากเมธอด โดยค่าที่รีเทิร์นออกไปจะไปอยู่ใน parameter ที่ 3 ของ componentDidUpdate method ที่จะถูกเรียกในอันดับถัดไป

สิ่งที่ทำได้

  • อ่านค่าของ current DOM หรือคำนวณค่าแล้วรีเทิร์นค่านั้นออกไป

สิ่งที่ไม่ควรทำ

  • ไม่ควรเรียก this.setState ในนี้เพราะจะทำให้เกิดการ render ตัวเองซ้ำๆ

componentDidUpdate(prevProps, prevState, snapshot)

เมื่อเมธอดนี้ถูกเรียก ก็แสดงว่าในตอนนี้ component นี้ และ children ที่อยู่ภายใต้ component นี้ถูก render เสร็จหมดแล้ว เมธอดนี้เหมาะสำหรับการทำ side effect ต่างๆ เช่น การ fetch data จาก api เวลาที่ props หรือ state เปลี่ยน

หากเรียก this.setState ใน เมธอดนี้ ก็จะทำให้เกิดการ rerender อีกครั้ง ต้องใช้ condition ในการดักให้ดีเพื่อป้องกันปัญหา performance ซึ่งเกิดจากการ render หลายครั้งตามมาได้

นอกจากนี้ เมธอดนี้ยังรับค่า snapshot ใน parameter ที่ 3 ซึ่งเป็นค่าที่ถูกรีเทิร์นมาจาก getSnapshotBeforeUpdate method เราสามารถนำค่านั้นมาใช้คำนวณเพื่ออัพเดท DOM ได้

สิ่งที่ทำได้

  • ทำ side effect ต่างๆ เช่นการ fetch data จาก api
  • สามารถเรียก this.setState ในเมธอดนี้ได้ แต่ควรเขียน condition ดักให้ดีเพื่อป้องกันการ render ตัวเองหลายรอบ

สิ่งที่ไม่ควรทำ

  • ไม่ควรเรียก this.setState หากไม่มีการเขียน condition ดักเพื่อป้องกันการ render ตัวเองหลายรอบ

ส่วนสุดท้ายเป็นส่วนของ life cycle methods ที่จะทำงานตอนการ Unmounting component ครับ

componentWillUnmount()

เมธอดนี้เป็นเมธอดสุดท้ายที่จะถูกเรียกก่อนที่ component จะถูก unmount ออกจาก DOM

โดยเมธอดนี้มักจะใช้ในการยกเลิกการกระทำต่างๆ ที่จะต้องมีการยกเลิกก่อนที่ component จะถูกทำลายไป เช่น การ unsubscriptions สิ่งต่างๆที่ถูก subscriptions ไว้ตอน componentDidMount หรือ การยกเลิกการ fetch data จาก api หรือการยกเลิก timers ต่างๆ (setTimeout, setInterval) ที่ได้ถูกเรียกใช้งานไว้

สิ่งที่ทำได้

  • ยกเลิกการกระทำต่างๆ ที่จะต้องมีการยกเลิก ก่อนที่ component ถูกทำลายไป

สิ่งที่ไม่ควรทำ

  • ไม่ควรเรียกใช้ this.setState ในเมธอดนี้
  • ไม่ควรเรียกใช้ timers ต่างๆ ในเมธอดนี้
  • ไม่ควร subscriptions สิ่งต่างๆ ในเมธอดนี้

สรุป

การเลือกใช้งาน component life-cycle methods ตามหน้าที่และความเหมาะสม จะทำให้เราสามารถ สร้าง component ที่ทำงานอย่างมีประสิทธิภาพได้

--

--