4 สิ่งอย่าหาทำของ React

Saracha Tongkumpunt
2 min readJun 6, 2021
Photo by Daniel Herron on Unsplash

1. ตั้งค่าเริ่มต้น state ด้วย props

ลองดูตัวอย่างด้านล่าง

จะเห็นว่ากด + แล้วก็ทำงานปกตินี่ แล้วอย่าหาทำยังไง? ประเด็นคือ

  • ถ้า props มีการเปลี่ยนแปลง state จะไม่เปลี่ยนตาม เพราะค่าใช้แค่ตอน initialise state ตอนแรก
  • ชื่อตัวแปรชวนสับสน อีกหน่อยถ้าโค้ดเยอะ ๆ หรือมีคนมาทำต่อ อาจจะงงได้

วิธีหลีกเลี่ยงความสับสนคือ ย้ายส่วนจัดการ state ไปที่ component App แล้วให้ component Counter แสดงผลจาก props อย่างเดียว
การทำแบบนี้จะเป็นการแยกส่วนการแสดงผล และส่วนการจัดการ state ออกจากกัน ทำให้โค้ดเป็นระเบียบมากขึ้นด้วย

ถ้าเลี่ยงไม่ได้จริง ๆ ที่จะต้องมี state ที่ส่วนแสดงผล ก็ตั้งชื่อ props เป็น initialCount ซะ เวลามาดูโค้ดตอนหลังจะได้ไม่งง

2. แก้ state ตรง ๆ โดยไม่ใช้ setState()

อันที่จริงถ้าเขียนด้วย Functinal Component กับ Hook เราจะไปแก้ state ตรง ๆ ไม่ได้อยู่แล้ว กรณีนี้จะเกิดขึ้นกับการเขียนแบบ Class Component (ซึ่งเอาจริง ๆ editor มันก็จะเตือนนะว่าอย่าหาทำ)
จากตัวอย่างด้านล่าง Codesandbox เตือนเลยว่าทำไม่ได้ ให้ไปใช้ setState() แทน

3. ใช้ index ของ Array เป็น key เวลา map item

เวลาเรา map item จาก Array เป็น JSX.Component ต่าง ๆ เนี่ย React ก็จะเตือนให้เราใส่ props key ไปด้วยเสมอ ซึ่งบางทีเราก็คิดไม่ออกว่าจะใช้อะไรเป็น key ดี ก็เอา index ของ Array นี่แหละไปใช้ แต่มันจะเกิดปัญหาเวลามีการเปลี่ยนอันดับใน Array นี่สิ

จากตัวอย่างด้านบน พอกด + แล้วก็พบว่าปกติดีนี่

ถ้าลองกรอกข้อความใน input box แล้วกด + จะพบว่า ปกติก็แย่แล้ว~

สาเหตุเกิดจาก index ของ Array เริ่มจาก 0 พอเราแทรก item ใหม่ไปที่ตำแหน่งแรก React เข้าใจผิดว่าเราแก้ไข input box สองอันเดิมไป ซึ่งไม่ต่างจากการไม่ใส่ key เลย
กรณีนี้แนะนำให้ใช้ key เป็น value ของ Array (ต้องมั่นใจว่าจะไม่มีข้อมูลซ้ำ) หรือใช้ unique identifier เช่น uuid

4. spread props ใน DOM elements

ท่านี้ใช้กันบ่อยมาก พบเจอได้แทบทุกที่

<Component {…props} />

ปัญหาของท่านี้อยู่ที่ว่า บางครั้งเราก็ไม่รู้ว่า props ที่ได้จากการ spread มันมีอะไรบ้าง บางตัวก็อาจจะไม่ใช่ HTML attributes ซึ่งอาจทำให้ขึ้น error หรือ warning ได้

สมมุติ Component เราเป็นแบบนี้

const Spread = () => <div foo=”bar” />;

เราดูจากโค้ดเนี่ย เราก็รู้ได้ว่าไม่ควรใส่ foo ไปใน <div> เพราะว่ามันไม่ใช่ HTML attributes ของ <div>
แต่ถ้าเรา spread props แบบด้านล่าง มันก็จะไล่ยากว่าเราเผลอใส่อะไรไป

const Spread = props => <div {…props} />;
//ตอนใช้
<Spread foo=”bar” className=”baz” />

ทางแก้คือ props ของ DOM ต่างหากอีกตัวนึงเลย ในที่นี้ตั้งชื่อว่า domProps แล้ว spread แต่ domProps

const Spread = props => <div {…props.domProps} />;
//ตอนใช้
<Spread foo="bar" domProps={{ className: 'baz' }} />

อีกทางแก้คือเขียนเป็น Typescript เพราะจะมีการเช็ค props ด้วย Interface เลยว่าจะต้องส่ง props อะไรมาบ้าง

อ้างอิง
Carlos Santana Roldán. (2019). React Design Patterns and Best Practices — Second Edition. Packt

--

--