บทความและข่าวสาร | Seven Peaks Insights

การเขียนโค้ด React แบบ clean, เคล็ดลับการทำ Context API, และการทำ automation testing สำหรับ React JS

Screenshot 2566-07-20 at 152039


เมื่อวันที่ 18 สิงหาคม 2021 Seven Peaks Software ได้จัดงานสัมมนาออนไลน์ขึ้นเพื่อพูดคุยเกี่ยวกับการพัฒนาซอฟต์แวร์ด้วย React JS หัวข้อการสัมมนาครั้งนี้คือ การ deploy แอปฯ ด้วย React อย่างมั่นใจ ซึ่งวิทยากรผู้เชี่ยวชาญด้าน React.js ทั้งสามท่านของเราจะมาแบ่งปันความรู้และประสบการณ์วิธีการสร้าง, ทดสอบ, และ deploy แอปพลิเคชันด้วย React อย่างมั่นใจเต็มที่ผ่านโครงสร้างการเขียนโค้ด React แบบ clean, เคล็ดลับการใช้งาน class component ของ React Context API, การทำ end-to-end test ด้วย Cypress testing framework, และอื่นๆ อีกมากมาย

 
Screenshot 2566-07-20 at 152401

 

การเขียนโค้ด React แบบ clean

คุณ Denis Pshenov เปิดงานสัมมนาออนไลน์ครั้งนี้ด้วยการนำเสนอหัวข้อ “สร้างประสิทธิภาพที่น่าประทับใจด้วย clean code” พร้อมทั้งกล่าวด้วยความมั่นใจเพื่อตอกย้ำความสำคัญของการรัน clean code ว่า “เมื่อเรารัน clean code แล้ว เราจะสามารถมีประสิทธิภาพที่ดีได้”

แล้วอะไรคือ clean code กันแน่ จริงๆ แล้วมันคือโค้ดที่สามารถเพิ่มความสามารถได้ง่าย และอ่านแล้วเข้าใจง่าย ซึ่งในกรณีที่มีสมาชิกในทีมเข้ามาใหม่ และยังไม่คุ้นเคยกับ codebase เขาก็สามารถเริ่มทำงานได้อย่างรวดเร็ว ช่วยให้พร้อมสำหรับการ implement ฟีเจอร์ใหม่ๆ และทำงานต่างๆ ได้ทันที

การ implement clean code นั้นเริ่มจากการตั้งชื่อให้ clean, มีความสม่ำเสมอ, การกำหนดคลาสให้มีหน้าที่เดียว และการหาแนวทางปฏิบัติที่ดีที่สุดสำหรับเป้าหมายของคุณแล้วนำไปใช้

สามารถ render ได้เร็วขึ้น

สามารถทำได้ด้วย 3 วิธีต่อไปนี้

  • Code Splitting
  • Tree Shaking
  • Lazy Loading

ตอบสนองต่อการใช้งานเร็วขึ้น

สามารถทำได้ด้วย 2 วิธีต่อไปนี้

  • ใช้ฟังก์ชันที่ render เร็ว
  • Render ใหม่เมื่อจำเป็นเท่านั้น

React นั้นทำงานอย่างรวดเร็ว โดยที่ส่วนใหญ่แล้วผู้ใช้ไม่จำเป็นต้องกังวลอะไรเลย แต่บางครั้งมันอาจจะทำงานช้าลงได้ เมื่อมันทำงานช้า เราก็ต้องทำความเข้าใจว่ามันช้าที่จุดใดและดูว่ามันช้ามากแค่ไหน ซึ่งมีเครื่องมือบางอย่างที่ช่วยให้เราสามารถตรวจสอบและชี้วัดปัญหาที่เกิดขึ้นได้ ดังนี้

  • Flame Graphs
  • React Dev Tools
  • React Profiler 
 
Writing-clean-React-code
 
Writing-clean-React-code-with-React-js-dev-tools


เมื่อคุณรู้แล้วว่ามีปัญหาอะไรในหน้านั้นแต่ยังไม่รู้ว่าทำไมถึงมีปัญหาเกิดขึ้น อะไรเป็นสาเหตุ รวมถึงอาจมีคำถามอื่นๆ การจะหาคำตอบได้นั้นคุณต้องเข้าใจก่อนว่า ทำไม React ถึงต้อง re-render บางอย่างด้วย?

  • React จะ re-render component เมื่อ state ที่อยู่ข้างในมีการเปลี่ยนแปลง
  • React จะ re-render เมื่อ parent ของ component นั้นถูก re-render

เมื่อมี component ที่ถูก re-render React จะไปยัง child ทุกตัวของ component นั้นแล้ว re-render child จากนั้นไปยัง Chip child ของ component แล้วทำการ re-render child ทั้งหมด

ดังนั้น เมื่อเรา re-render จากส่วนบนสุดของ React tree มันจะไปกระทบกับ component จนถึง node สุดท้ายและมันจะส่งผลกระทบต่อประสิทธิภาพการทำงานอย่างใหญ่หลวง คุณจึงต้อง optimize ให้ดีตั้งแต่ส่วนบนสุดเพื่อไม่ให้มัน re-render ตั้งแต่ส่วนบนบ่อยเกินไป

บางครั้งคุณอาจต้องแชร์การใช้งาน state ระหว่าง component หลายๆ ตัว ซึ่งทำให้คุณต้องใช้ global state ซึ่งการบริหารจัดการ global state ที่ดีนั้นคุณควรใช้ NPM Library อย่างเช่น

      • Redux
      • Context API
      • Zustand (ดูแลโดย Dashi Kato)
      • Jotai (หรือ Recoil)
      • Constate
      • ใช้ Context Selector
        เป็นต้น

และยังมีวิธีการอื่นอีกในการ optimize ระบบที่คุณสามารถทำได้ แต่ไม่ได้ใช้หลักการ clean code เช่น

  • useMemo
  • useCallback
  • UseRef”
 

ดูการสาธิตวิธีการเขียน React แบบ clean code ได้ข้างล่างนี้

สร้างประสิทธิภาพที่น่าประทับใจด้วย clean code

Screenshot 2566-07-20 at 162342


React Context API 

วิทยากรท่านที่สองของเรา คุณ Huad ที่จะมาเจาะลึกถึงการทำ Context API ผ่านการสาธิตเคล็ดลับในการใช้งาน รวมถึงสิ่งที่ควรทำและไม่ควรทำเกี่ยวกับ Context API ที่จะช่วยให้คุณสามารถใช้งานมันได้อย่างเต็มประสิทธิภาพ

“Context API มีวิธีในการส่งผ่านข้อมูลไปยัง component tree โดยไม่ต้องส่ง props แบบแมนวลไปยังทุกๆ level”
– จาก https://reactjs.org/docs/context.html

“อีกวิธีที่ทำให้คุณสามารถแชร์ข้อมูล (state) ได้แบบ implicit ระหว่าง component หลายๆ ตัว”– กล่าวโดยคุณ Huad

คุณ Huad บอกว่า Context API เป็นอีกวิธีหนึ่งในการที่คุณสามารถแชร์ข้อมูล (state) ได้แบบ implicit ระหว่าง component หลายๆ ตัว เนื่องจาก Context API นั้นมีไว้ใช้สำหรับการแชร์ state หรือข้อมูล ซึ่งสำหรับหลักการทำงานของ React แล้ว การแชร์ข้อมูลก็คือการส่งผ่าน props นั่นเอง

“สรุปแล้ว ปัญหาที่แท้จริงก็คืออะไร และทำไมคุณถึงต้องใช้ Context API ด้วย ในเมื่อคุณสามารถส่งผ่าน props เฉยๆ ก็ได้? นั่นก็เพราะคุณจะเจอปัญหาเมื่อคุณต้องส่งผ่านไปยังหลายๆ level”

ปัญหานี้เรียกว่า props drilling ซึ่งจะเกิดขึ้นเมื่อคุณต้องส่งผ่านข้อมูลหรือ props ไปยังหลายๆ level แล้ว component ในระดับกลางไม่จำเป็นต้องรู้ข้อมูลนี้ ซึ่งจะกลายเป็นปัญหาที่น่าหงุดหงิดสำหรับบางคนได้

ปัญหาที่เกิดขึ้นจาก props drilling นั้นสามารถแก้ไขได้ด้วย Context API สิ่งแรกที่เราจะ import คือฟังก์ชันที่เรียกว่า createContext ใน React ซึ่งใช้เพียงพารามิเตอร์เดียวเท่านั้น ได้แก่ default value ที่เราเพิ่งกำหนดไปว่า undefined หรือถ้าคุณใช้ TypeScript ก็สามารถส่งค่านี้ได้

ถ้าคุณใช้ JavaScript ก็สามารถปล่อยมันไว้แบบนั้นได้ เมื่อเรียกใช้ createContext คุณจะได้ object instance จาก Context API จากนั้นคุณก็จะได้ Context API และวิธีใช้งานมัน

ผลของการเรียก createContext คือ คุณจะได้ object instance ของ Context API และใน instant property คุณก็จะเพิ่ม component ที่เรียกว่า Provider ซึ่งคุณก็แค่ต้องสร้าง component ที่จำเป็นต้องมี props เพื่อเริ่มทำงาน ซึ่งก็คือ value โดยเราจะใช้งาน value ดังกล่าวใน Context API

คุณแค่สร้าง component ขึ้นมาหนึ่งตัวแล้วทำการ wrap มันซะ ทุกอย่างก็จะอยู่ในนั้น เมื่อคุณใช้งาน Context API คุณก็แค่ใช้ Hook จาก React ด้วยการเรียกใช้ Hook ที่ชื่อว่า useContext แล้วส่งผ่าน useContext แทน

โดยมันจะคืนค่าเป็น value ที่คุณส่งไปยัง Provider ก่อนหน้านี้ ซึ่งเป็น object ที่บรรจุค่าของสีที่ใช้อยู่และ สีสำหรับ Sip”

React-context-api-class-component
 

ดูวิดีโอสาธิตการเขียนโค้ดแบบสดๆ เกี่ยวกับ React Context API ได้ข้างล่างนี้

React Context API โดยคุณ Huad.

 
Screenshot 2566-07-20 at 162927


หลักการของ Testing Pyramid: การใช้ Cypress testing framework, React Testing Library, และอื่นๆ อีกมากมาย

วิทยากรท่านสุดท้ายของเราคือ คุณ Georgii ที่มาสาธิตวิธีการ deploy แอปพลิเคชัน React อย่างมั่นใจด้วยการทำการทดสอบภาคปฏิบัติด้วยหลักการ Testing Pyramid ผ่านการใช้งาน React Testing Library และ Cypress

คุณ Georgii เริ่มด้วยการอธิบายว่าคุณต้องคาดหวังอะไรจาก release บ้างเมื่อต้องการสร้างแอปพลิเคชันขึ้นมา ซึ่งได้แก่

  • ฟีเจอร์ใหม่ทำงานได้ตามที่คาดหวัง
  • ไม่มีบั๊ก
  • ไม่มีการแก้ไข

เอาละ แล้วทำไมเราจึงต้องเขียน test ขึ้นมาใน front end ของแอปพลิเคชันของเราด้วย นั่นก็เพราะว่า

  • ลูกค้าเกลียดบั๊กในผลิตภัณฑ์เวอร์ชัน final
  • การปรับโครงสร้างโค้ดนั้น โดยเฉพาะในส่วนใหญ่ๆ เป็นสิ่งที่น่าปวดหัวมาก เนื่องจากคุณจะกังวลว่าอาจจะไปทำอะไรบางอย่างพังก็ได้
  • การแก้ไขผลิตภัณฑ์ที่ไปอยู่ใน production แล้วจะมีต้นทุนที่สูงมาก
  • เพื่อประหยัดทั้งเงินและเวลา

แนวคิดพื้นฐานของการทำ test นั้นสามารถวางโครงสร้างออกมาเป็น Testing Pyramid ได้ดังนี้

  • ขั้นที่ 1 คือ Unit Test
  • ขั้นที่ 2 คือ Integration Test
  • ขั้นที่ 3 คือ End-to-end Test
 
 
React-app-integration-testing-pyramid
 
React-apps-integration-tests


แนวคิดหรือกระบวนการทำงานดังกล่าวสามารถนำไปใช้กับ backend ได้ง่ายๆ ในด้านของ Unit Test นั้น หากคุณทำ TDD (Test-driven development) มันก็เหมือนกับการเขียน Unit Test ก่อนที่จะเขียนโค้ดนั่นเอง

สำหรับ Integration Test นั้น คุณจะเขียนน้อยกว่านิดหน่อย แต่คุณต้องตรวจสอบว่า API ทำงานอย่างไรด้วยการเรียกใช้ API แล้วดูว่ามันตอบสนองอย่างถูกต้องหรือไม่ โดย endpoint นั้นเป็นเหมือนกับบุรุษไปรษณีย์หรืออะไรทำนองนั้น ซึ่งคุณจะเรียกใช้ Rail API แล้วดูว่าเกิดอะไรขึ้นกับข้อมูลจริงบ้าง

แต่ใน backend นั้น คุณจะเห็นความล้มเหลวของ End-to-end Test ได้ทันที แต่การทำ test แต่ละแบบก็มีประโยชน์ในแบบของมันเอง

มาต่อกันทีเรื่องของ Testing Trophy กัน ซึ่งคุณ Georgii เริ่มด้วยรากฐานของแนวคิดที่เกี่ยวกับ Static Check ตามด้วยการทำ Unit Test, Integration Test, และ End-to-end Test

มีเครื่องมืออะไรบ้างที่สามารถนำมาใช้กับ test แต่ละแบบได้

  • Static Checks – Typescript, EsLint, Flow
  • Unit Tests – Jest
  • Integration Tests – Jest + React testing library
  • End to End Tests – Cypress”

“เขียน test อย่าให้เยอะเกินไป เน้น integration เป็นหลัก”
– โดย Guillermo Rauch

 

ดูวิดีโอสาธิตการเขียนโค้ดแบบสดๆ เกี่ยวกับ Integration และ End-to-end Testing ได้ข้างล่างนี้

Testing Pyramid โดยคุณ Georgii.

 
คุณเป็น Frontend (React.js) Developer ที่มีความสามารถใช่ไหม
ดูตำแหน่งงาน Senior, Mid-level, และ Junior Frontend Developer ที่เปิดรับสมัครได้ข้างล่างนี้
ดูตำแหน่งงาน Frontend Developer ที่เปิดรับสมัคร