Class

ภาษาโดยทั่วไปนั้น ต่างก็มี concept เรื่อง class ของตัวเองกัน ดังนั้น ใน React จึงได้กำหนดวิธีการสร้าง class ผ่านคำสั่ง React.createClass ซึ่งก็ไม่เลว แต่มันยังไม่ใช่วิถีที่ดูเป็นมาตรฐานในการสร้าง class ซักเท่าไหร่

ES6 คลอดออกมาพร้อมกับแนวคิดเรื่อง class ทำให้เราสามารถ migrate จาก React.createClass มาใช้ ES6 class ได้ โดยเราจะเริ่มต้นจาก class ดังต่อไปนี้

code ข้างต้นนั้นคือ TodoApp component ซึ่งมีครบทุกรสชาติของการเป็น component เพราะมีทั้ง state, props และมีการส่ง props ให้ลูกๆ ด้วย

คราวนี้ลองมาดูกันว่า หากเราจะแปลง code ข้างต้นให้กลายมาเป็น ES6 class จะเป็นแบบไหน

ต่อไปนี้คือจุดที่แตกต่างกันระหว่าง class แบบเก่า กับ ES6 class

  1. ไม่มี createClass อีกต่อไป แต่เปลี่ยนเป็นการสร้าง class ที่ extends React.Component
  2. มี constructor ที่ใช้สำหรับ initialize ค่าต่าง ซึ่งในที่นี้คือการ initial state ให้กับ component ทำให้ getInitialState ไม่จำเป็นอีกต่อไป และสิ่งที่อยากให้สังเกตุอีกอย่างก็คือ เวลาสร้าง constructor ให้เราเรียก super() ด้วยทุกครั้ง เพราะมันคือการ call constructor ของ React.Component ให้ทำงานก่อนทุกครั้ง
  3. ‘,’ ระหว่าง function หรือ properties หายไป
  4. PropTypes ถูกจับออกมาประกาศไว้พื้นที่ด้านนอก class โดยจะแทรกไว้ด้านล่าง ซึ่งเป็นวิธีเดียวกับที่เราทำตอนที่เราสร้าง Stateless Functional Components
  5. ตอนที่เราใช้ createClass ตัว ‘this.<functionName>‘ จะถูก bind ให้กับ class โดยอัตโนมัติอยู่แล้ว ซึ่งคุณไม่จำเป็นต้องไปยุ่งกับมันมาก แต่พอเราใช้ ES6 class คุณสมบัตินี้จะหายไป (เป็นข้อเสียของฟีเจอร์นี้) ดังนั้น เวลาคุณจะส่งผ่าน this.<functionName> ไปยังฟังก์ชั่น หรือใน component อื่น ให้ใช้วิธี .bind ก็จะแก้ปัญหานี้ได้ แต่จะให้สวย ใช้ Arrow Function ก็น่าจะเป็นการดี ยกตัวอย่างจาก code ข้างบน ดัง code ต่อไปนี้ ซึ่งจะใช้ Arrow Function ในการส่งผ่าน function this.updateItems() ไปยัง TodoForm component ที่สำคัญก็คือ หลังชื่อฟังก์ชั่นต้องใส่เครื่องหมาย () ด้วย

Project Refactoring

ConfirmBattleContainer refactoring

ให้เปิดไฟล์ app/containers/ConfirmBattleContainer.js ขึ้นมาแล้วแก้ code ดังนี้

PromptContainer refactoring

ให้เปิดไฟล์ app/containers/PromptContainer.js ขึ้นมาแล้วปรับ code ดังนี้

จาก code ข้างต้น หากสังเกตดีๆ จะมี code อยู่ตอนหนึ่งที่ผมอยากจะพูดถึง นั่นคือ

onSubmitUser เป็น callback function ที่จะถูก call จาก Prompt component (ตัวลูก) ซึ่งจะมาพร้อมกับ event object ด้วย ซึ่งรายละเอียดการทำงานนั้น คุณผู้อ่านสามารถดูได้จากรูปดังต่อไปนี้

screen-shot-2559-11-12-at-6-13-05-pm

จากรูป จะมีการทำงานอยู่ 3 ขั้นตอน

  1. ผู้ใช้กดปุ่ม Continue
  2. ตัว onChange event จะถูก call จากนั้นมันก็จะวิ่งไปหา callback ที่ถูกเซตไว้เพื่อรองรับ event ตัวนี้ พร้อมกับส่งผ่าน event object ไปเป็น argument ให้กับ callback function ดังกล่าวด้วย
  3. พบว่า ได้เซตให้ handleSubmitUser ของ PromptContainer เป็น callback function ดังนั้น จึงรับ event object เข้ามาเป็น argument โดยส่งผ่าน Arrow Function

ResultsContainer refactoring

ให้เปิด app/containers/ResultsContainer.js แล้วปรับ code ดังนี้

หลังจากนั้นให้ลองเปิดระบบแล้วทำการทดสอบเต็มรูปอีกครั้งหนึ่ง

สำหรับผู้ที่อยากได้ code ต้นแบบ ให้ไปดูได้ที่

https://github.com/himaeng/react-fun-course/tree/master/ES06-class

สรุป

นี่คือเนื้อหาในตอนสุดท้ายของคอร์ส ES6/7 for React โดยตอนนี้เราคุยกันเรื่องของ class ที่ดูแล้วก็ไม่ได้มีข้อดีมากมายจนถึงกับต้องเปลี่ยนจาก React.createClass มาใช้มัน ดังนั้น หากใครจะใช้ React.createClass ต่อไปก็ไม่น่าจะมีปัญหาอะไร เพราะมันเป็นเรื่องของรสนิยมล้วนๆ แต่ประโยชน์ที่คุณผู้อ่านได้ไปแล้วแน่ๆ ก็คือ สามารถเขียนได้ทั้งแบบ createClass และ ES6 class

1 COMMENT