React มือใหม่ part 1: using TypeScript

Phai Panda
5 min readFeb 13, 2021

--

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

เนื้อหาที่อยากเล่าใน part นี้ประกอบด้วย

  • เตรียมความพร้อม เครื่องคอมฯและติดตั้งโปรแกรมที่จำเป็น
  • สร้าง React ด้วย TypeScript โครงสร้างของโปรเจกต์
  • Home Component ตัวอย่าง function component
  • About Component ตัวอย่าง function component + array function
  • Basic React Routing
  • Lifecycle Methods

เตรียมความพร้อม

  • เครื่อง MacOS ปี 2018
  • MS VS Code ที่นี่ เป็น editor ช่วยเขียนโปรแกรม
  • ดาวน์โหลด Node.js ที่นี่ แล้วติดตั้งให้เรียบร้อย

เมื่อเราติดตั้ง Node.js เราจะได้โปรแกรม NPM เป็นตัวจัดการ JavaScript packages ย่อมาจาก Node Package Manager

ติดตั้ง create-react-app

ที่ Terminal พิมพ์

npm install -g create-react-app

React ก็คือไลบรารี JavaScript ดังนั้นเราสามารถใช้ NPM ช่วยติดตั้งมันได้

มือใหม่อาจสงสัยว่าทำไมต้องพึ่งพา NPM? คำตอบที่เป็นหัวใจคือเราต้องการมันมาจัดการ JavaScript dependencies

คำว่า JavaScript dependencies นี้หมายถึง JavaScript package ที่มีมากกว่าหนึ่งและมันต้องทำงานร่วมกัน เวอร์ชันไหนเข้ากันได้ ปรับปรุงเวอร์ชัน เพิ่มและลบ package ต่างๆที่ต้องการ

npm install -g จะบอกให้ติดตั้งโปรแกรมต่อไปนี้ในระดับ global สามารถเรียกใช้ได้ทุกที่ ส่วน create-react-app คือชื่อโปรแกรมดังกล่าว

สร้าง React ด้วย TypeScript

จริงอยู่ React สามารถเขียนด้วย .js แต่เราจะเขียนมันด้วย TypeScript (.ts) แทน

มือใหม่อาจสงสัยว่าทำไมต้องพึ่งพา TypeScript? คำตอบที่เป็นหัวใจคือเราต้องการไทป์หรือชนิดข้อมูลเพื่อลดความผิดพลาดในขณะที่กำลังพัฒนาโปรแกรม

create-react-app try-react --template typescript

คำสั่งข้างต้นกล่าวว่าสั่งให้ใช้โปรแกรม create-react-app สร้างโปรเจกต์ชื่อ try-react โดยใช้ TypeScript

เข้าไปในโปรเจกต์แล้วพิมพ์

npm run build

คำสั่งนี้จะสร้าง folder ชื่อ build ภายในนั้นคือโปรเจกต์ของเราที่พร้อม deploy บน production server

ความแตกต่างระหว่าง production server กับ local server

local server นี้หมายถึงเครื่องคอมฯของเราเอง เมื่อติดตั้ง Node.js เราก็มี Node.js เป็นโปรแกรม web server คอยจัดการประดา requests ให้ ส่วน production server นั้นไม่ใช่คอมฯของเรา เราจะต้องติดตั้งหรือเลือกใช้บริการโปรแกรม web server ที่เข้าใจโปรเจกต์ของเราครับ

โปรเจกต์ที่ต้อง deploy บน production server (remote เพื่อ upload โปรเจกต์ไปวาง) ควรจะมีขนาดเล็กเพื่อให้ผู้ใช้งานโหลดได้ไวในขณะที่ใช้ความเร็วอินเตอร์เน็ตต่ำ คำสั่ง npm run build จะทำหลายอย่างเพื่อให้โปรเจตก์เราพร้อมสำหรับเรื่องนี้ อ่านเพิ่มเติม ที่นี่

โครงสร้างโปรเจกต์

folder ชื่อ build ซึ่งเกิดจากคำสั่ง npm run build สามารถลบและสั่งสร้างได้ตลอด โครงสร้างของโปรเจกต์เพิ่งสร้างขึ้นเป็นดังนี้

  • node_modules ภายในคือ JavaScript dependencies สามารถลบและสั่งสร้างได้ตลอดด้วยคำสั่ง npm install
  • public ภายในคือ static assets หรือไฟล์ content ที่จำเป็นต่อ npm run build
  • src ย่อมาจาก source หรือไฟล์ตั้งต้นในการพัฒนาโปรเจกต์ ประกอบด้วยไฟล์ .tsx คือ React component,.ts คือ TypeScript, .css คือ CSS และ d.ts คือ TypeScript ที่ TypeScript compiler ใช้เพื่อตรวจสอบไทป์
  • .gitignore เป็นส่วนหนึ่งของการพัฒนาโปรเจกต์โดยมี Git เป็นผู้แล source code ใช้เพื่อละเว้น folder หรือกลุ่มไฟล์ที่เราไม่สนใจและไม่ต้องการ commit เข้า Git repository
  • package.json (และ package-lock.json) ใช้กำหนด dependencies ทั้งหมดในโปรเจกต์ของเรา เป็นหัวใจของโปรเจตก์ที่สร้างจาก Node.js
  • tsconfig.json ใช้ตั้งค่าเพื่อบอกกล่าวแก่ TypeScript compilter ให้ตรวจสอบไทป์ใน .ts

การพัฒนา React ด้วย TypeScript จะอยู่ใน strict mode กล่าวคือจะเข้มงวดกับไทป์ หากเขียนผิดไวยากรณ์จะไม่ compile ให้ อ่านเพิ่มเติม ที่นี่

index.tsx

เปิดไฟล์ src/index.tsx

ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);

ไฟล์ใดก็ตามที่บรรจุ React component จะใช้สกุล .tsx ไฟล์ชื่อ index.tsx นี้คือจุดเริ่มต้นของเราและถูกเรียกว่า entry point

โปรดสังเกตว่า ReactDOM.render ต้องการ 2 ค่า

  1. component ที่จะถูก render นั่นคือ <App/> ที่ถูกห่อหุ้มด้วย React.StrictMode
  2. จุดที่จะ render ซึ่งก็คือ div element ในไฟล์ public/index.html ที่มี id ชื่อ root

App.tsx

<App/> ถูกประกาศไว้ในไฟล์ src/app.tsx ฟังก์ชัน App เมื่อเขียนเป็นแท็กเปิดและปิดจึงได้ว่า <App/>

function App() {
return (
<div className="App">
<header className="App-header">
...
</header>
</div>
);
}

เราเรียกการเขียนลักษณะนี้ว่า component

JSX

จากตัวอย่างโค้ดของ src/app.tsx หน้าตาของ component ใดๆจะถูก render หลังคำสั่ง return (...) โดยไวยากรณ์ที่เขียนภายใน (...) นี้เรียกว่า JSX ซึ่งไม่ใช่ HTML (JSX ย่อมาจาก JavaScript XML) หรือพูดง่ายๆคือ XML ที่ท้ายที่สุดจะถูกเปลี่ยนเป็น JavaScript/ECMAScript ปกติที่ browser เข้าใจ

เพราะความคุ้นเคยบ่อยครั้งที่ผมมักเขียน class แทนที่จะเขียน className เข้าไปในแท็ก มือใหม่พอจะทราบแล้วว่า class ใช้กับ HTML และแน่นอนว่า JSX ไม่รู้จักมัน

รันโปรเจกต์

พิมพ์คำสั่งต่อไปนี้เพื่อเริ่มทำงาน Node.js และดูผลลัพธ์ที่ได้

npm start

ที่ http://localhost:3000

การแก้ไขไฟล์​ .tsx จะ re-render อัตโนมัติเราไม่ต้องไป stop แล้ว start server เอง (ดีใช่ไหมล้า~)

Home Component

เราจะสร้าง component แรกกัน ชื่อว่า Home

จาก src folder สร้างไฟล์ชื่อ Home.tsx

import React from 'react'function Home() {
return (
<div>Hello World! Home</div>
)
}
export default Home

มือใหม่จะสังเกตว่าเครื่องหมาย ; ท้าย statement จะมีหรือไม่ก็ได้

About Component

เราจะสร้าง About component ที่เขียนต่างจาก Home component เล็กน้อย

สร้างไฟล์ src/About.tsx

import React, { FC } from 'react'const About: FC = () => {
return <div>I am About.</div>
}
export default About

FC คือ function component เขียนด้วย arrow function

ทั้ง Home component และ About component ต่างกันแค่วิธีเขียนฟังก์ชันแค่นั้น มือใหม่ก็เลือกเอาตามใจชอบ

Basic React routing

คงดีไม่น้อยถ้าเราได้เพิ่ม Home และ About ไว้กับ routing เพื่อสลับการ render

เปิดไฟล์ src/index.tsx เพิ่ม BrowserRouter

import { BrowserRouter } from 'react-router-dom'

แต่ VS Code ไม่รู้จัก นั่นแสดงว่าเราต้องบอก npm ให้ช่วยติดตั้ง react-router-dom ก่อน

npm i react-router-dom

คำสั่ง install สามารถเขียนย่อได้ด้วย i

เนื่องจากโปรเจกต์ใช้ TypeScript ดังนั้นเพิ่ม @Types ของ react-router-dom ด้วย

npm i --save-dev @types/react-router-dom

ไฟล์ package.json จะมีส่วนที่เรียกว่า dependencies และ devDependencies สองส่วนนี้ต่างกันที่ devDependencies ใช้ในช่วงพัฒนาโปรเจกต์เท่านั้น จะไม่ถูก bundle เข้ากับโค้ด production

คราวนี้แทรก BrowserRouter เข้าไป

ReactDOM.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>,
document.getElementById('root')
);

เท่ากับว่า component ใดภายใต้ App component ได้สมบัติการ routing

เปิดไฟล์ src/App.tsx ปรับปรุง JSX

import React from 'react';
import './App.css';
import { Route, Switch } from 'react-router-dom';
import Home from './Home';
function App() {
return (
<div className="App">
<header className="App-header">
<Switch>
<Route path='/' component={Home}></Route>
</Switch>

</header>
</div>
);
}
export default App;

ผลลัพธ์

งดงาม

เพิ่ม About component เข้าไปที่ /about

import About from './About';
...
<Switch>
<Route path='/about' component={About}></Route>
<Route path='/' component={Home}></Route>
</Switch>

ที่ http://localhost:3000/about

ดูแพง

Lifecycle Methods

https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/

มือใหม่คงทราบว่า React ใช้กลไกของ virtual DOM แทนที่จะ render HTML ลงบน DOM จริงๆ ความเร็วที่เกิดจาการใช้ memory ส่วนนี้แลกกับการ re-render เฉพาะส่วนใดส่วนหนึ่งของ component ที่เกิดการเปลี่ยนแปลงเท่านั้นมันแสนคุ้มค่า

การเปลี่ยนแปลง (changed) ดังกล่าวเกิดจากสิ่งที่ React เรียกว่า State

State ก็คือออบเจ็กต์ที่บรรจุสารพัด properties ไว้ภายใน เมื่อฟังก์ชัน setState ถูกเรียกก็กระตุ้นให้เกิดการ re-render

จากรูปข้างต้นนี้แบ่งได้ 2 phases

  1. Render phase
  2. Commit phase

ทั้ง 2 phases ประกอบด้วย Mounting, Updating และ Unmounting

Mounting จะจองหน่วยความจำ (initialization) และเพิ่ม component ไปยัง virtual DOM

Updating เกิดขึ้นเพื่อ re-render ผลคือ UI เกิดการเปลี่ยนแปลง (รวมถึง data ที่แสดงบน UI เปลี่ยนแปลง)

Unmounting เมื่อใดก็ตามที่ component ไม่ถูกใช้งานมันจะถูกลบออกจาก DOM

Lifecycle Methods ถือเป็นหัวใจของ React เขียนได้ 2 รูปแบบ

  1. Class-style components (ดั่งเดิม)
  2. Functional components

ซึ่งจะขอกล่าวรายละเอียดใน part ถัดไปนะครับ

--

--

No responses yet