Skip to main content
เทคโนโลยี

มาขยับจาก React JS เป็น React TS กันเถอะ !

“มาตามหาคำตอบกันว่าเพราะอะไร ? ทำไมเราควรเปลี่ยนจาก React JS มาเป็น React TS ? วันนี้เราจะมาลองให้ดูกันแบบเต็ม ๆ ตา”

**บทความนี้ใช้ตัวอย่างโค้ดที่เขียนด้วย React แบบ Functional และใช้ VS code ในการ Compile และเขียนโค้ด

เขียนโดย
Developer @ borntoDev

สำหรับใครที่กำลังเขียนหรือกำลังพัฒนาเว็บด้วย React อยู่น่าจะคุ้นเคยกับการใช้ JavaScript (JS) เป็นอย่างดี ซึ่งหลายคนอาจจะเคยเห็น TypeScript (TS) ผ่านตามาบ้างและกำลังลังเลว่าจะลองขยับมาใช้ TS ดีมั้ย? ในเมื่อมันทำงานอย่างเดียวกันได้จะเปลี่ยนไปใช้ให้ยุ่งยากทำไม?

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

 

ขั้นตอนการติดตั้งแบบง่าย ๆ

ให้เราสร้าง React App ขึ้นมาด้วยคำสั่งด้านล่าง

(ถ้า Folder Code มีไฟล์ .tsx ขึ้นมาแสดงว่าเรามาถูกทางแล้ว)

npx create-react-app name-of-app --template typescript

ตัวอย่างการสร้าง Component สำหรับแสดงผลการคำนวณ VAT

  • การประกาศ Component JS

export default function VatResult({price, rate}) {
  return (
    <div>
      {price+(price*rate/100)}
    </div>
  )
}

โค้ดตัวอย่างการเขียน Component ในไฟล์ .jsx ที่เราคุ้นเคยกันดี โดยมันจะรับ Prop 2 ตัวคือ price (ราคาสินค้า) และ rate (อัตรา % ของ VAT) แล้วนำมาแสดงผลการคำนวณ

  • การประกาศ Component TS

ถ้าเราเอาโค้ดแบบเดียวกันมาประกาศในไฟล์ .tsx เราก็จะโดนเตือน Error เรื่องที่เรายังไม่ได้กำหนด Type ทันที

ซึ่งวิธีประกาศ Type ให้เราสร้างตัวแปรประเภท type ขึ้นมาแล้วกำหนด Type ให้ Prop ตามตัวอย่างด้านล่าง

(สำหรับใครที่สงสัยเรื่อง Type ของ TypeScript อ่านเพิ่มเติมได้ที่นี่เลย TypeScript: Documentation – Everyday Types (typescriptlang.org))

type Prop = {
  price: number
  rate: number
}

export default function VatResult({price, rate}: Prop) {  
  return (
    <div>
      {price*rate}
    </div>
  )
}

พอเราสร้าง Component ทั้ง 2 แบบออกมาแล้วลองส่ง Prop price เป็นค่า String ดูจะเห็นว่า Component TS ที่กำหนด Type price เป็น number จะแสดง error ออกมา

สำหรับ JavaScript ถ้าเรายังไม่ได้รันโค้ดเพื่อดูผลลัพธ์เราก็จะยังไม่รู้ว่าการใส่ค่าเป็น String จะทำให้ผลลัพธ์การทำงานผิดไปจากที่เราต้องการ

<VatResultJS price={'9000'} rate={7}/>
<VatResultTS price={9000} rate={7}/>

ผลลัพธ์ที่เกิดขึ้นจากการรันเทียบกันระหว่าง (1) การใส่ค่า ‘9000’ ที่เป็น String และ (2) การใส่ค่า 9000 ที่เป็น Number

9000630
9630

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

ในกรณีที่เราอยากละ Prop บางตัวให้ใช้ค่า Default ใน TypeScript

เราสามารถทำได้ด้วยการใช้เครื่องหมาย ? ตอนที่ประกาศ Type สำหรับ Prop บางตัวเพื่อกำหนดให้ไม่จำเป็นต้องส่งมาตอนเรียกใช้ Component ได้ตามโค้ดด้านล่าง

type Prop = {
  price: number
  rate?: number
}

และใน Component ก็สามารถกำหนดค่า Default ในกรณีที่ไม่ได้ส่ง Prop ตัวนั้นมาด้วย (กรณีไม่ใส่จะเป็น undefined)

export default function VatResultTS({price, rate = 7}: Prop) {
  return (
    <div>
      {price+(price*rate/100)}
    </div>
  )
}

ตอนนี้เราก็สามารถเรียกใช้ Component VatResultTS โดยที่ส่งเพียงค่า price แล้วใช้ rate ที่ 7% ได้

<VatResultTS price={9000}/>

ผลลัพธ์ที่ออกมา

9630

อยากได้ Function คำนวณราคาสินค้าจากตะกร้าด้วย

ตัวอย่างที่มีการใช้ Type เป็น number หรือ string อาจจะยังไม่เห็นภาพประโยชน์ของ TypeScript เท่าที่ควร ลองมาดูตัวอย่างเคสที่เกิดขึ้นกับ Array ของ Object กันดูบ้าง

  • ตัวอย่างข้อมูลที่ไม่สอดคล้องกัน

const cart = [
    { productName: 'a', price: 199 },
    { productName: 'b', price: 248 },
    { productName: 'c', price: '268' }
]
  • การประกาศ Function JS

function calculatePriceJS(cart) {
  return cart.reduce((sumPrice, product) => sumPrice + product.price, 0)
}

Function JS ที่ใช้ reduce เพื่อหาผลรวมของ Property price ในแต่ละ Object ภายใน Array ที่ส่งเข้ามา

ความน่ากลัวของมันคือพอประกาศด้วย JavaScript Output ที่ Return ออกจาก Function จะเป็น Type any เสมอ ซึ่งต่อให้ Component TypeScript ที่มารับค่าไปใช้จะกำหนด Type ไว้แล้วมันก็ยังปล่อยให้ผ่านไปได้แม้อาจจะทำให้เกิดผลลัพธ์ที่ไม่ถูกต้องก็ตาม

44726831308.76
  • การประกาศ Function TS

ประกาศ Type ให้ข้อมูลก่อน Object แต่ละตัวก่อน

type cartType = {
  productName: string
  price: number
}

นำ Type ที่ประกาศไว้แล้วมาต่อด้วยเครื่องหมาย [] เพื่อประกาศเป็นตัวแปรประเภท Array ของ Type นั้น ๆ

function calculatePriceTS(cart: cartType[]) {
  return cart.reduce((sumPrice, product) => sumPrice + product.price, 0)
}

เมื่อนำมาลองใช้ด้วยข้อมูลเดิมก็จะโดน Error ว่าข้อมูลที่รับเข้ามามี 2 แบบ แต่ตอนที่ประกาศรับได้แบบเดียว แปลว่าข้อมูลไม่เหมาะสมที่จะนำมาใช้กับ Function นี้

เมื่อเรารู้ก็เปลี่ยนข้อมูลให้ถูกต้อง

const cartEdited = [
    { productName: 'a', price: 199 },
    { productName: 'b', price: 248 },
    { productName: 'c', price: 268 }
]

เมื่อเปลี่ยนข้อมูลให้ Type ถูกต้องก็จะไม่ Error แล้ว

ผลลัพธ์การรันเปลี่ยนเทียบตอนที่ยังไม่แก้และหลังจากแก้ข้อมูลแล้ว

44726831308.76
765.05

 

สรุปข้อดีจากการเปลี่ยนมาใช้ TS

  • เหมือนมี Doc ในตัว ทำให้อ่านโค้ดได้ง่ายขึ้น Component นี้ Prop รับค่าอะไรได้บ้าง ต้องใส่เป็นอะไร

  • ช่วยให้เราเจอบัคในบางเคสก่อนโค้ดจะรัน

    • ปกติ Prop ใน JS เราไม่สนใจว่ามันมีอะไรอยู่บ้างแต่ ใน TS เราต้องประกาศไว้ก่อน

การใช้ TypeScript ด้วย React ( ทั้งการใช้ในรูปแบบอื่น ) ไม่ได้ช่วยให้โค้ดที่ใช้เขียนสั้นลง (  จริง ๆ แล้ว TS เขียนยาวกว่าแน่ ๆ ) หรือทำงานได้ดีกว่า JavaScript สำหรับใครที่เขียนโค้ดทั้ง Project คนเดียวหรือเขียนต่อเนื่องมาเรื่อย ๆ ทำให้สามารถจำโค้ดทั้งหมดได้อยู่แล้ว ก็อาจไม่จำเป็นต้องใช้ TypeScript เลยก็ได้ แต่สำหรับงานที่โค้ดมีขนาดใหญ่ขึ้นกว่านั้นหรืองานที่คนพัฒนาเปลี่ยนแปลงไปเรื่อย ๆ การกำหนด Type ด้วย TypeScript จะช่วยให้ Developer คนอื่น ๆ ในทีมเข้าใจโค้ดของคุณได้ง่ายขึ้น และช่วยให้ลดเวลาการทำงานในการอ่านโค้ดของคนในทีมระยะยาวได้

เราใช้คุกกี้เพื่อพัฒนาประสิทธิภาพ และประสบการณ์ที่ดีในการใช้เว็บไซต์ของคุณ คุณสามารถศึกษารายละเอียดได้ที่ นโยบายความเป็นส่วนตัว และสามารถจัดการความเป็นส่วนตัวเองได้ของคุณได้เองโดยคลิกที่ ตั้งค่า

ตั้งค่าความเป็นส่วนตัว

คุณสามารถเลือกการตั้งค่าคุกกี้โดยเปิด/ปิด คุกกี้ในแต่ละประเภทได้ตามความต้องการ ยกเว้น คุกกี้ที่จำเป็น

ยอมรับทั้งหมด
จัดการความเป็นส่วนตัว
  • คุกกี้ที่จำเป็น
    เปิดใช้งานตลอด

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

  • คุกกี้สำหรับการติดตามทางการตลาด

    ประเภทของคุกกี้ที่มีความจำเป็นในการใช้งานเพื่อการวิเคราะห์ และ นำเสนอโปรโมชัน สินค้า รวมถึงหลักสูตรฟรี และ สิทธิพิเศษต่าง ๆ คุณสามารถเลือกปิดคุกกี้ประเภทนี้ได้โดยไม่ส่งผลต่อการทำงานหลัก เว้นแต่การนำเสนอโปรโมชันที่อาจไม่ตรงกับความต้องการ
    รายละเอียดคุกกี้

บันทึกการตั้งค่า