10 Tips for React.js beginner
1. Variable Naming
เป็นหัวข้อที่เจอบ่อยๆในหลายๆบทความ เป็นเรื่องที่เหมือนจะง่ายแต่เอาเข้าจริงก็ยากพอควร Rule of thumb ส่วนตัวก็คือ
- ตั้งชื่อตัวแปร(รวมถึงชื่อ component)ให้เจาะจงไว้ก่อน — ใช้
exportButton
แทนที่จะเป็นbutton
ถึงแม้ว่าทั้งหน้าจะมีอยู่ปุ่มเดียว เหตุผลคือในอนาคตถ้ามีการเพิ่มปุ่มไปในหน้านี้ dev คนถัดไปอาจจะเพิ่มremoveButton
จะกลายเป็นว่าหน้านี้มีbutton
กับremoveButton
ซึ่งก็ไม่สวย และเค้าอาจสาปส่งเราได้ถ้าเค้าต้องไปแก้ชื่อปุ่มเก่าให้มันเข้าใจง่ายขึ้น - คุยกับตัวเองให้จบก่อน เลือกมา verb เดียวสำหรับการทำอะไรสักอย่าง แล้วตั้งเป็นกฏของตัวเอง / ทีมไปเลย เช่น เลือกระหว่าง
handleSomething
หรือonSomething
get
/find
insert
/add
etc …
ส่วนตัว declare function ด้วย handle และส่งลงไปใน props ด้วย onXXX)
handleButtonClicked = () => { .... }<OtherComponent onClick={handleButtonClicked} />
เหตุผลคือพวก onClick นั้นจะตาม convention ของ DOM อยู่แล้ว ส่วนพวก handle คือเรียกตาม recompose (มันใช้ withHandler อะ) อันนี้เป็น convention ส่วนตัว คนอื่นอาจจะใช้ on ทั้ง function ทั้ง props หรืออะไรก็ได้ แต่ควรเซตให้เหมือนกันทั้ง codebase
2. ใช้ลิ้น :)
ใช้เถอะคับ หมายถึง eslint นะ (ใช้ trim white space ด้วยก็ดีนะ)
3. Extract Constant
ว่าจะไม่ใส่ แต่ก็เจอเรื่อยๆ ไอเดียคือไม่ควรใช้พวก string เช่น ‘SOME_STRING’ ใน condition / code เราซ้ำๆ ถ้าเราเจอมากกว่า 1 ที่ (หรือที่จริงแค่ที่เดียวก็ได้แล้ว) ควรจะแยกไปใน constants แล้ว import มา อันนี้คล้ายๆ shotgun surgery เหตุผลคือถ้าค่านั้นเปลี่ยนเราจะได้เปลี่ยนแค่ที่เดียวครับ
4. ลองใช้ sourcemap / debug บน web browser
React มันเป็น frontend js เนอะ ถ้าเราเซต sourcemap ถูก เราสามารถเปิด developer tool แล้วเปิด component (Cmd + O)วาง debug ดูโฟลวของคอมโพเน้นเราได้เลย ไม่ต้องไปแก้โค้ด + recompile
5. Try setting up your own web app. Don’t rely on bootstrap / scaffolding
เหตุผลคือ จากประสบการณ์ หลายๆครั้งที่ tool พวกนี้ ให้ของที่เราไม่ได้อยากได้มาเต็มไปหมด จนบางทีเราต้องไปหาวิธีไม่เอามัน หรือถ้ามีอะไรที่เราอยาก ก็ต้องไปนั่งดูว่ามันมีมาหรือยัง เพิ่มได้ไหม เปลี่ยนเจ้าได้ไหม แก้ยังไง ซึ่งผมชอบที่จะวางเองมากกว่า รู้สึกว่าทุกอย่างอยู่ในการควบคุมของเราเอง อาจจะดูเสียเวลา แต่เชื่อว่าได้เรียนรู้และคลีนกว่าแน่นอนครับ
อย่าพึ่งไปห่วงว่ามันไม่เท่ห์ มานั่งเขียนอะไรพวกนี้ ใช้ tool ปรื้ดๆ ดีกว่า
6. Don’t use Redux — just yet
หลายๆคน (ผมด้วย) เริ่มต้นหัดเขียน React ด้วยการอ่านบทความใน internet หรือดูพวกคอร์สออนไลน์ แล้วพบว่าส่วนใหญ่มักจะสอน React คู่กับพวก state management นี้ แล้วก็ไปทำตามจนกลายเป็นว่ามันเป็นของที่ต้องใช้ไป ทั้งๆที่ ที่จริงแล้วผมเชื่อว่าเกิน 50% ของ web app ที่เราทำ ไม่จำเป็นต้องใช้ Redux เลย ตรงกันข้าม การใช้ Redux กลับเป็นการเพิ่ม boilerplate ซึ่งลด productivity ของเราด้วยซ้ำ
ส่วนตัวคิดว่า Redux เหมาะสำหรับเว็บที่แต่ละหน้าใช้ information ร่วมกัน แชร์กัน ในขณะที่เว็บที่เราทำส่วนใหญ่จะ hold/use information ของตัวเองเท่านั้น มักจะใช้ info global แค่ไม่กี่อย่าง ซึ่ง Redux overkill มากๆ
สำหรับคนที่เริ่มต้น React อยากให้ลองเขียน Pure React ก่อน หา common ancestor / ส่ง props ไป child component ทำจนรู้สึกถึง pain ของมัน หรือรู้สึกว่ามันแปลกๆ(ถ้ารู้สึก) แล้วค่อยลอง redux ครับ
ส่วนตัวตอนนี้ใช้ Apollo local state
7. Don’t use Recompose — just yet
เคยเขียนไปทีนึงแล้ว แต่ก็ขอยกมาพูดอีกว่าเราอาจจะไม่จำเป็นต้องใช้ recompose ถ้าเราไม่ได้รู้สึกว่ามันช่วยอะไรอย่างเห็นได้ชัด Don’t be a hipster that use all the cutting edge libs and later regret it. Instead, try to see benefit of each lib before adding it to your code base ครับ New libs introduce to your codebase oftentimes also introduce learning curve and complexity ครับ
8. ใช้ React.PureComponent แทน React.Component
มือใหม่หลายๆคนอาจจะไม่รู้ว่า React มันมี PureComponent ด้วยนะ ข้อแตกต่างก็คือ PureComponent มันจะใช้ shallow comparison ตอนเช็คว่า shouldComponentUpdate ครับ (ทำให้เร็วกว่า) ส่วนในด้านการเขียนแล้วไม่ได้ต่างกันเท่าไหร่เพราะเวลาเรา update state เรามักจะไม่ mutate อยู่แล้ว ซึ่ง purecomponent ก็จะ trigger update เช่นเดียวกับ Component เลย
9. รู้ความแตกต่างระหว่าง Smart Component และ Dumb Component
บอกก่อนว่าที่จริงแล้วพวกนี้มันเป็นแค่ concept ที่มีคนคิดขึ้นมา มันไม่ได้เป็นกฏ หรือ set in the stone ขนาดนั้นนะครับ ส่วนตัวเริ่มรู้สึกว่าเส้นมันเริ่มบางๆขึ้นหลังจาก GraphQL + Apollo มา wrap component ได้นะ
ไอเดียตั้งต้นก็คือ ถึงแม้ว่า react มันจะเป็น component based แต่แทนที่เราจะทำ component แบบกระจัดกระจายต่างคนต่างทำงาน เราอยากให้มี component ใหญ่ๆตัวนึงที่เป็นเสมือนพื้นให้ component ย่อยๆ แต่ละตัวมาวางบนมัน ซึ่งเราควรจะแยกระหว่าง component สองชนิดนี้ และเขียนพวกจัดการ data / request อะไร บน component ใหญ่ (Smart Component) แล้วค่อยส่งพวก data ลงไป component เล็ก (Dumb Component) เพื่อแสดงผล
ข้อดีก็คือ โค้ดจะเป็นระเบียบขึ้น (pain ที่เจอกันแต่ก่อนก็คือต่างคนต่างเรียก แล้วมันงงๆว่า ดาต้าตรงนี้มันมาจากไหน คือไม่เป็นระเบียบว่างั้นเถอะ) นอกจากนี้เมื่อทำแบบนี้ Dumb Component ก็จะไม่ผูกติดกับ library หรือวิธีการที่เราหา data มาด้วย
ข้อเสียก็คือมันต้อง pass function ในการส่ง request ไปที่ dumb component นะ เพราะ dumb component ต่อเองไม่ได้ ทำได้แค่รู้ว่าตอนปุ่มนี้โดนกด จะเรียกฟังก์ชั่นอะไรสักอย่าง
อย่างไรก็ตาม ส่วนตัวรู้สึกว่า Dan จะ over concern กับเรื่องการเปลี่ยน lib เกินไปอะ ตั้งแต่ตอนทำพวก mapDispatchToProps ละ คืออันที่จริงผมรู้สึกว่าเราไม่ได้เปลี่ยน lib บ่อยขนาดนั้นอะนะ พอผมมาลองเล่น apollo แล้วกลับรู้สึกว่าการ wrap component ลูกด้วย query / mutation ก็ไม่ได้เลวร้ายอะไรขนาดนั้น หลังๆเลยเริ่มปล่อยละ ไม่รู้คนอื่นคิดยังไง
10. รู้ว่าเมื่อไหร่ควรเป็น shared component เมื่อไหร่ควรแยก
ข้อนี้อาจจะยาก ไอเดียก็คือเวลามี requirement มา หลายๆครั้งเราจะเจอว่าเราสามารถทำเป็น shared component ได้ คำถามก็คือเราควรจะทำรึเปล่า บางคนก็แนะนำสุดโต่งไปเลยว่า ไม่ควร เพราะในอนาคตอาจมี requirement ให้สองอันนี้มันทำงานไม่เหมือนกัน แล้วสุดท้ายเราก็ต้องไปทำ component ที่ว่าให้รับตัวแปรมา custom หรือไม่ก็ต้องแยก component (pain ทั้งคู่)
ส่วนตัวก็ยังมีปัญหากับเรื่องนี้อยู่เวลาต้องตัดสินใจ แต่เห็นด้วยกับหลายๆเจ้าที่ว่า DRY ไม่ใช่ golden rule ไม่ต้อง shared component ซะทุกอย่างก็ได้ (แต่บางเจ้าก็ continous refactoring พอเจอว่าจะทำไม่เหมือนกันค่อยแยก)