ตอนที่ 1 - เริ่มต้นเขียน React.js

Published on

เขียนวันที่ : Jun 11, 2022

react-2022/01-hello-react
Discord

สวัสดีครับ ขอต้อนรับเข้าสู่เนื้อหา React.js ฉบับเริ่มต้น (ปี 2022) โดยเนื้อหา เหมาะสำหรับมือใหม่หัดเขียนนะครับ เน้นพื้นฐาน และมีตัวอย่างง่ายๆ ให้ลองทำ ลองฝึกครับ

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

เตรียมพร้อมสำหรับการเขียน React ครับ สิ่งที่ต้องมีคือ

  • VS Code - ตัว Text Editor สำหรับเขียนโค๊ด
  • Prettier - เป็น Extension ของ VS Code เอาไว้ช่วย format โค๊ดของเรา
  • Node / npm - เพื่อใช้ในการติดตั้ง React หรือ JavaScript library ต่างๆ
  • Terminal - มี Command Line Tool หรือจะใช้ built-in ใน VS Code ก็ได้
  • JavaScript - เข้าใจการเขียน JavaScript เบื้องต้น
  • เข้าใจ HTML & CSS - หากไม่เคยเขียนเลย แนะนำ HTML คือ? สอนเขียน HTML สำหรับมือใหม่แบบละเอียด - designil

ติดตั้ง VS Code

ตัว VS Code ถือเป็นเครื่องมือที่เอาไว้เขียนโปรแกรมยอดนิยมตัวนึง VS Code โดยรองรับทุกๆ Platform ไม่ว่าจะเป็น Windows, Mac หรือ Linux หากใครยังไม่มี แนะนำทำการติดตั้ง VS Code ก่อน ถ้ามีแล้ว ก็ข้ามขั้นตอนไปได้ครับ

ติดตั้ง Node.js

เราจะใช้ Node.js ซึ่งเป็น JavaScript runtime เพื่อที่เราจะสามารถติดตั้ง JavaScript library อื่นๆ หรือติดตั้ง React เพื่อสร้างเว็บด้วย React

วิธีการติดตั้ง Node.js เข้าหน้าเว็บไซต์และกด Download ได้เลย แนะนำเป็นตัว LTS เวอร์ชั่น ซึ่งปัจจุบัน ณ​เวลาที่เขียนบทความ คือ Version 16.15.1LTS

เมื่อทำการติดตั้ง Node.js เรียบร้อยแล้ว ให้เราทำการเปิด Terminal ขึ้นมา (หรือเปิด VS Code และกด View -> Terminal) จากนั้นพิมพ์

node --version

เพื่อเช็คว่าเราได้ทำการติดตั้ง Node.js เรียบร้อยแล้ว ถ้าถูกต้อง เราจะได้เลข version ของ Node.js ของเรา

ตัว Node จะติดตัว npm และ npx มาให้เรา (ใช้ในการติดตั้ง library ต่างๆ)

Hello World

เริ่มต้น React ด้วยการใช้เครื่องมือที่ชื่อว่า create-reacta-app โดยตัวอย่าง เราจะทำการสร้างโปรเจ็ค โดยตั้งชื่อว่า hello-app

คำสั่งก็จะได้เป็นแบบนี้

npx create-react-app hello-app

ตัว script จะทำการ สร้าง React app และทำการ Install package ต่างๆ ใช้เวลาซักครู่นึง

React 2022 - Hello App

เมื่อตัว script ทำงานเสร็จ เราจะเห็น folder hello-app ที่ข้างในประกอบไปด้วย Folder ต่างๆ ดังนี้

└── hello-app
    ├── README.md
    ├── package-lock.json
    ├── package.json
    ├── public
    │   ├── favicon.ico
    │   ├── index.html
    │   ├── logo192.png
    │   ├── logo512.png
    │   ├── manifest.json
    │   └── robots.txt
    └── src
        ├── App.css
        ├── App.js
        ├── App.test.js
        ├── index.css
        ├── index.js
        ├── logo.svg
        ├── reportWebVitals.js
        └── setupTests.js

ทดลอง start server ขึ้นมาดู (ต้องรันคำสั่งจาก folder hello-app)

cd hello-app

จากนั้นพิมพ์

npm start

เมื่อเราเปิดเว็บ http://localhost:3000 เราก็จะเห็น Web React ของเรา หน้าตาประมาณนี้

React 2022 - Hello App2

Component

ใน React ตัว Component เป็นสิ่งที่เราจะได้ยินบ่อยๆมากๆ และในโลกของ React เราจะมองสิ่งต่างๆ เป็น Component ครับ เช่น หน้า Google เราอาจจะแบ่งเป็น

  • Component สำหรับ SearchBox เพื่อค้นหา
  • Component สำหรับหน้า Display รายการที่ค้นหา autocomplete
  • Component สำหรับ Result ที่ค้นหาได้

ซึ่ง การจะกำหนดว่า Component มีมากน้อยแค่ไหน มีอะไรบ้าง ก็ไม่มีตายตัวครับ ขึ้นอยู่กับความต้องการของเรา

จากโค๊ดที่ create-react-app Generate มาให้ เราลองเปิดไฟล์ src/App.js ขึ้นมาดู (ซึ่งถ้าเรามองจริงๆ มันก็คือ Component App.js นั่นเอง)

import logo from './logo.svg';
import './App.css';

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;

ใน React Component ก็คือ JavaScript function ธรรมดาๆ นี่แหละครับ แต่ที่พิเศษมาหน่อย คือมันเป็น function ที่ return JSX

JSX คืออะไร?

JSX คือ JavaScript syntax extension พูดง่ายๆ คือ JavaScript แบบพิเศษ เพื่อใช้งานร่วมกับ React ตัว syntax จะหน้าตาคล้ายๆ HTML

const element = <h1>Hello, World!</h1>;

ซึ่งเราจะเห็นว่า มันไม่ใช้ String หรือไม่ใช่ HTML (แต่มีความคล้าย นั่นเอง) ทำให้เราสามารถแทรกตัวแปร หรือค่าต่างๆ ของ JavaScript ลงไปได้ แบบนี้

const name = 'John Doe';
const element = <h1>Hello, {name}</h1>;

ลองเปรียบเทียบ ถ้าสมมติ JSX ที่เป็น img ของ HTML:

<img src="/image/url.png" alt="Image" />

ถ้าเป็น JSX ตัว จะหน้าตาแบบนี้

<img src={`/image/url.png`} alt="Image" />

หรือ

const srcUrl = '/image/url.png'
<img src={srcUrl} alt="Image" />

สังเกตเห็นว่า ใน JSX เราจะใช้ closing tag กับพวก empty tag เลย เช่น <img />

นอกจากนี้ JSX attribute ต่างๆ เราจะใช้ camelCase เช่น ปกติ HTML เราจะใช้ class แต่ JSX จะเป็น className

สร้าง New Component

หลังจากรู้ JSX และ Component คร่าวๆ ไปแล้ว ลองมาสร้าง Component ขึ้นมา เราตั้งชื่อให้มันว่า HelloWorld.js สร้างไว้ใน src

src/HelloWorld.js
const HelloWorld = () => {
  return <h1>Hello World</h1>;
};

export default HelloWorld;

โดย Component นี้ เป็นเพียงแค่การแสดงผล Hello World ออกมาเท่านั้น วิธีใช้งาน Component ที่เราสร้างขึ้น ก็แค่ import มาใช้ครับ (สังเกตว่าเราใช้ export default HelloWorld เพื่อ export component นี้ให้ component อื่นๆ สามารถใข้งานได้)

แก้ไฟล์ src/App.js และ import เพิ่ม HelloWorld ลงไป ข้างใน <div className="App">

src/App.js
import logo from "./logo.svg";
import "./App.css";

import HelloWorld from "./HelloWorld";

function App() {
  return (
    <div className="App">
      <HelloWorld />

      // code อื่นๆ
    </div>
      );
}

ลองกลับไปดูหน้าเว็บ http://localhost:3000 จะเห็นว่าเรามี HelloWorld แสดงที่ด้านบนของเว็บเรา

สังเกตว่า เราไม่จำเป็นต้องทำการ Refresh หน้าเว็บเลย เนื่องจากเพราะ create-react-app มี script ที่ช่วยทำงานส่วนนี้ให้เราอยู่

ปัญหา

ในการที่เราสร้าง Component เราจำเป็นต้อง wrap สิ่งต่างๆ ให้อยู่ใน element tag เดียว เช่น

<div>...</div>

แต่ไม่สามารถทำแบบนี้ได้

return (
  <div />
  <div />
  <p>paragraph</p>
)

ทดลองโดยการแก้ไขไฟล์ src/App.js และลองย้าย <HelloWorld /> ไปไว้ก่อน <div ดูครับ แบบนี้

src/App.js
import logo from "./logo.svg";
import "./App.css";

import HelloWorld from "./HelloWorld";

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

export default App;

เราจะเห็นว่ามัน Error ทันที และขึ้นข้อความประมาณว่า Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment ...?

ถ้าเราอยากให้ Component return หลายๆ JSX element จริงๆ เราก็ใช้สิ่งที่เรียกว่า React Fragment ครับ คือใช้ <React.Fragment> หุ้ม ก่อนและหลัง หรือ short hand มันคือ <>...</> ตามที่ Error แนะนำครับ

src/App.js
import logo from "./logo.svg";
import "./App.css";

import HelloWorld from "./HelloWorld";

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

export default App;

แบบฝึกทบทวน

  1. ลองสร้าง Component ขึ้นมาใหม่ โดยมีหลายๆ element ครับ และลองใช้ React.Fragment ดู
  2. ฝึกอ่าน Error message กรณีที่เราทำผิดพลาด อย่างเช่นเรื่องของ JSX จะมี Error บอกว่าบรรทัดไหนของโค๊ด รวมถึงคำแนะนำ
  3. อ่าน React - Quick Start เพิ่มเติม

References

Buy Me A Coffee
Discord