สร้าง Front-End ด้วย React

front-end สำหรับ developer จะเรียกกันสั้น ๆ ว่า หน้าบ้าน หรือเป็นส่วนติดต่อผู้ใช้ (User interface) ไม่ว่าจะเป็น หน้าโฮม หน้าเว็บเพจ เนื้อหาต่างๆ รูปภาพ ลิงก์ เป็นต้น เป็นส่วนที่ user ทั่วไปสามารถเห็นและเข้ามาใช้งานได้ของเว็บไซต์

ในการสร้าง web application ในฝั่งของ User Interface ในปัจจุบันนั้นมีความซับซ้อนเพิ่มมากขึ้นจากสมัยก่อนมากเนื่องจากผู้ใช้งาน internet สามารถเข้าถึง website ต่าง ๆ ผ่านทาง smart phone, tablet หรือ laptop ได้อย่างง่ายดาย ดังนั้น web application ที่เราใช้จะมีความซับซ้อนของการใช้งานเพิ่มมากขึ้น ซึ่งการที่จะพัฒนาโปรแกรมจึงทำได้ยากกว่าสมัยก่อน จึงมีผู้ริเริ่มพัฒนาเครื่องมือที่จะมาช่วยทุ่นแรงให้กับ developer ซึ่งก็คือ front-end framework นั่นเอง โดยหลัก ๆ แล้วจะช่วยให้การเขียนโค้ดทำได้รวดเร็วประหยัดเวลามากขึ้น และช่วยเรื่องของ performance ในการใช้งานที่ต้องทำงานได้อย่างลื่นไหลเปรียบเสมือนการใช้งาน application ทั่วไป

React Framework ตัวนี้ถูกพัฒนาโดย Facebook ในปี 2013 ซึ่ง concept ของ React คือ javascript library (เครื่องมือ JS) สำหรับสร้าง User Interface ซึ่งทำให้มันมีขนาด bundle size ที่เล็ก ถ้าต้องการความสามารถด้านอื่น ๆ เช่น Routing, Http request ก็สามารถติดตั้ง third party library เพิ่มเติมได้ตามความต้องการ


สร้างโปรเจค React 


สร้างโปรเจค React ด้วยการเปิด “Command Prompt” โดยไปที่ ช่องค้นหา พิมพ์ cmd เลือก Command Prompt


ใช้คำสั่งในการสร้างโปรเจ็ค React คือ

npx create-react-app go-movies


เปิด Visual Studio Code ขึ้นมา ไปที่ File -> Open Folder… เลือกไปที่โฟลเดอร์ go-movies


ลบไฟล์ส่วนที่เลือก


ที่ไฟล์ index.js ลบโค้ดบางส่วนออก


ที่ไฟล์ App.js ลบโค้ดบางส่วนออก


ที่ไฟล์ index.html ลบโค้ดบางส่วนออก และที่ title แก้เป็น Go Watch Movies


ใช้ CSS ของ Bootstrap


Bootstrap คือ Frontend Framework ที่รวม HTML, CSS และ JS เข้าด้วยกันสำหรับพัฒนา Web ที่รองรับทุก Smart Device หรือ เรียกว่า Responsive Web หรือ Mobile First Bootstrap ถูกพัฒนาขึ้นโดยทีมงานจาก Twitter หรือ Twitter.com

โดย สามารถสร้างหน้าเว็บให้ตรงตามแบบที่เราต้องการได้ง่ายขึ้น เพราะ Bootstrap มีทั้งระบบ grid ที่ช่วยเรื่องการวาง layout ที่รองรับในแบบ responsive และมี component สำเร็จรูปให้ใช้ ถ้าเราอยากได้ของที่ต้องใช้บ่อยๆ แต่ไม่อยากคราฟเองเช่น table card หรือปุ่มสวยๆ bootstrap ก็สามารถช่วยให้เราสร้างขึ้นมาได้ง่ายๆ ตามแบบที่ bootstrap ได้วางไว้อีกด้วย

ไปที่ https://getbootstrap.com/ แล้วคลิกที่เมนู Docs แล้ว Copy โค้ดด้านล่าง CSS

เพิ่มโค้ดด้านล่าง Go Watch Movies

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">


ที่ไฟล์ App.js เขียนโค้ดดังนี้

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

      <div className="row">
        <h1 className="mt-3">
          Go Watch a Movie!
        </h1>
        <hr className="mb=3"></hr>
      </div>

      <div className="row">
        <div className="col-md-2">
          <nav>
            <ul className="list-group">
              <li className="list-group-item">
                <a href="/">Home</a>
              </li>
              <li className="list-group-item">
                <a href="/movies">Movies</a>
              </li>
              <li className="list-group-item">
                <a href="/admin">Manage Catalogue</a>
              </li>
            </ul>
          </nav>
        </div>

        <div className="col-md-10">

        </div>
      </div>
    </div>    
  );
}

export default App;


ทดสอบการทำงาน

npm start


ที่เว็บเบราว์เซอร์ 


ติดตั้ง react-router-dom


React Router คือ module ที่ทำหน้าที่ในการ Navigating หรือการเปลี่ยน page ไปมา ภายในระบบของ React นั้นคือการที่เราทำให้ app ของเรานั่นมีเพจหลายหน้า เรียกว่า Multi pages Application โดยเมื่อผู้ใช้ต้องการไปยังเว็บเพจนั้นก็จะสามารถกรอก URL หรือคลิกที่ลิงก์แล้วเปลี่ยนไปยังหน้าเว็บเพจปลายทางที่เราได้ทำการกำหนดไว้ได้นั่นเอง

npm install react-router-dom@v5.3.0


ที่ไฟล์ App.js เขียนโค้ดดังนี้

import React, { Fragment } from 'react';
import {BrowserRouter as Router, Switch, Route, Link} from 'react-router-dom';

export default function App() {
  return (
    <Router>
    <div className="container">

      <div className="row">
        <h1 className="mt-3">
          Go Watch a Movie!
        </h1>
        <hr className="mb=3"></hr>
      </div>

      <div className="row">
        <div className="col-md-2">
          <nav>
            <ul className="list-group">
              <li className="list-group-item">
                <Link to="/">Home</Link>
              </li>
              <li className="list-group-item">
                <Link to="/movies">Movies</Link>
              </li>
              <li className="list-group-item">
                <Link to="/admin">Manage Catalogue</Link>
              </li>
            </ul>
          </nav>
        </div>

        <div className="col-md-10">
          <Switch>
            <Route path="/movies">
              <Movies />
            </Route>
            <Route path="/admin">
              <Admin />
            </Route>
            <Route path="/">
              <Home />
            </Route>
          </Switch>
        </div>
      </div>
    </div> 
    </Router>   
  );
}

function Home() {
  return <h2>Home</h2>
}

function Movies() {
  return <h2>Movies</h2>
}

function Admin() {
  return <h2>Manage Catalogue</h2>
}


ทดสอบการทำงาน


ที่เว็บเบราว์เซอร์ (ทดสอบคลิกเมนูต่างๆ)


Copmonent


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

สร้างโฟลเดอร์ components ภายในโฟลเดอร์ src แล้วสร้างไฟล์คอมโพเนนท์ ชื่อ Movies.js มีโค้ดดังนี้

import React, { Component } from 'react';

export default class Movies extends Component {
    render() {
        return(
            <h2>Choose a movie</h2>   
        );
    }
}


ที่ไฟล์ App.js นำเข้า คอมโพเนนท์ ชื่อ Movies ด้วยคำสั่ง

import Movies from './components/Movies';


ที่ TERMINAL จะแสดง ERROR ให้ลบโค้ดฟังค์ชั่น Movies ออกทั้งหมด


ที่เว็บเบราว์เซอร์ เมื่อทดสอบคลิกที่เมนู Movies (http://localhost:3000/movies) จะแสดงข้อความที่มาจาก คอมโพเนนท์ ชื่อ Movies ( Movies .js)


ดังนั้นเราจะใช้หลักการเดียวกันในการสร้าง คอมโพเนนท์ ชื่อ Home และ Admin


ที่ไฟล์ App.js นำเข้า คอมโพเนนท์ Home และ Admin


ลบโค้ดฟังค์ชั่น Home และ Admin ออก


State


ข้อมูลที่อยู่ใน Component แต่ละชิ้น เราเรียกว่า State


ที่ไฟล์คอมโพเนนท์ Movies เขียนโค้ดดังนี้

import React, { Component, Fragment } from "react";

export default class Movies extends Component {
  state = { movies: [] };

  componentDidMount() {
      this.setState({
          movies: [
              {id: 1, title: "The Shawshank Redemption", runtime: 142 },
              {id: 2, title: "The Godfather", runtime: 175 },
              {id: 3, title: "The Dark Knight", runtime: 153 },
          ]
      })
  }

  render() {
    return (
      <Fragment>
        <h2>Choose a movie</h2>

        <ul>
            {this.state.movies.map( (m) => (
                <li key={m.id}>
                    {m.title}
                </li>
            ))}
        </ul>
      </Fragment>
    );
  }
}


ที่เว็บเบราว์เซอร์ ทดสอบคลิกที่เมนู Movies 


เพิ่ม Link ให้กับ Choose a movie


ที่ไฟล์ App.js นำเข้า useParams


เพิ่ม Route path


เพิ่ม function Movie

ไฟล์คอมโพเนนท์ Movies เพิ่มโค้ด import { Link } from ‘react-router-dom’;


และ <Link to={`/movies/${m.id}`}>{m.title}</Link>

โค้ดดังนี้

import React, { Component, Fragment } from "react";
import { Link } from 'react-router-dom';

export default class Movies extends Component {
  state = { movies: [] };

  componentDidMount() {
      this.setState({
          movies: [
              {id: 1, title: "The Shawshank Redemption", runtime: 142 },
              {id: 2, title: "The Godfather", runtime: 175 },
              {id: 3, title: "The Dark Knight", runtime: 153 },
          ]
      })
  }

  render() {
    return (
      <Fragment>
        <h2>Choose a movie</h2>
        <ul>
            {this.state.movies.map( (m) => (
                <li key={m.id}>
                    <Link to={`/movies/${m.id}`}>{m.title}</Link>
                </li>
            ))}
        </ul>
      </Fragment>
    );
  }
}


ที่เว็บเบราว์เซอร์ ทดสอบคลิกรายการล่าง Choose a movie


เพิ่ม Categories


ภายในโฟลเดอร์ components สร้างไฟล์คอมโพเนนท์ ชื่อ Categories.js มีโค้ดดังนี้


ที่ไฟล์ App.js เขียนโค้ด ดังนี้

import React, { Component, Fragment } from 'react';
import {BrowserRouter as Router, Switch, Route, Link, useParams, useRouteMatch} from 'react-router-dom';
import Movies from './components/Movies';
import Admin from './components/Admin';
import Home from './components/Home';
import Categories from './components/Categories';

export default function App() {
  return (
    <Router>
    <div className="container">

      <div className="row">
        <h1 className="mt-3">
          Go Watch a Movie!
        </h1>
        <hr className="mb-3"></hr>
      </div>

      <div className="row">
        <div className="col-md-2">
          <nav>
            <ul className="list-group">
              <li className="list-group-item">
                <Link to="/">Home</Link>
              </li>
              <li className="list-group-item">
                <Link to="/movies">Movies</Link>
              </li>
              <li className="list-group-item">
                <Link to="/by-category">Categories</Link>
              </li>
              <li className="list-group-item">
                <Link to="/admin">Manage Catalogue</Link>
              </li>
            </ul>
          </nav>
        </div>

        <div className="col-md-10">
          <Switch>
            <Route path="/movies/:id">
              <Movie />
            </Route>
            <Route path="/movies">
              <Movies />
            </Route>
            <Route exact path="/by-category">
              <CategoryPage />
            </Route>

            <Route 
            exact
            path="/by-category/drama"
            render={(props) => <Categories {...props} title={`Drama`} />}
            />

          <Route 
            exact
            path="/by-category/comedy"
            render={(props) => <Categories {...props} title={`Comedy`} />}
            />

            <Route path="/admin">
              <Admin />
            </Route>
            <Route path="/">
              <Home />
            </Route>
          </Switch>
        </div>
      </div>
    </div>
    </Router>
  );
}

function Movie() {
  let { id } = useParams();

  return <h2>Movie id {id}</h2>
}

function CategoryPage() {

  let { path, url } = useRouteMatch();

  return (
    <div>
      <h2>Categories</h2>

      <ul>
        <li><Link to={`${path}/comedy`}>Comedy</Link> </li>
        <li><Link to={`${url}/drama`}>Drama</Link> </li>
      </ul>
    </div>
  );
}



ที่เว็บเบราว์เซอร์ ทดสอบคลิก Categories


แสดง Movie 1 รายการ


ภายในโฟลเดอร์ components สร้างไฟล์คอมโพเนนท์ ชื่อ OneMovie.js มีโค้ดดังนี้

import React, { Component, Fragment } from 'react'

export default class OneMovie extends Component {

    state = { movie: {} };

    componentDidMount() {
        this.setState({movie: {
            id: this.props.match.params.id,
            title: "Some movie",
            runtime: 150,
        }})
    }

    render() {
        return (
            <Fragment>
                <h2>Movie: {this.state.movie.title} {this.state.movie.id}</h2>

                <table className="table table-compact table-striped">
                    <thead></thead>
                    <tbody>
                        <tr>
                            <td><strong>Title:</strong></td>
                            <td>{this.state.movie.title}</td>
                        </tr>
                        <tr>
                            <td><strong>Run time:</strong></td>
                            <td>{this.state.movie.runtime} minutes</td>
                        </tr>
                    </tbody>
                </table>
            </Fragment>
        );
    }
}


ที่ไฟล์ App.js เขียนโค้ด ดังนี้

import React, { Component, Fragment } from 'react';
import {BrowserRouter as Router, Switch, Route, Link, useParams, useRouteMatch} from 'react-router-dom';
import Movies from './components/Movies';
import Admin from './components/Admin';
import Home from './components/Home';
import Categories from './components/Categories';
import OneMovie from './components/OneMovie';

export default function App() {
  return (
    <Router>
    <div className="container">

      <div className="row">
        <h1 className="mt-3">
          Go Watch a Movie!
        </h1>
        <hr className="mb-3"></hr>
      </div>

      <div className="row">
        <div className="col-md-2">
          <nav>
            <ul className="list-group">
              <li className="list-group-item">
                <Link to="/">Home</Link>
              </li>
              <li className="list-group-item">
                <Link to="/movies">Movies</Link>
              </li>
              <li className="list-group-item">
                <Link to="/by-category">Categories</Link>
              </li>
              <li className="list-group-item">
                <Link to="/admin">Manage Catalogue</Link>
              </li>
            </ul>
          </nav>
        </div>

        <div className="col-md-10">
          <Switch>
            
            <Route path="/movies/:id" component={OneMovie} />

            <Route path="/movies">
              <Movies />
            </Route>
            <Route exact path="/by-category">
              <CategoryPage />
            </Route>

            <Route 
            exact
            path="/by-category/drama"
            render={(props) => <Categories {...props} title={`Drama`} />}
            />

          <Route 
            exact
            path="/by-category/comedy"
            render={(props) => <Categories {...props} title={`Comedy`} />}
            />

            <Route path="/admin">
              <Admin />
            </Route>
            <Route path="/">
              <Home />
            </Route>
          </Switch>
        </div>
      </div>
    </div>
    </Router>
  );
}

function CategoryPage() {

  let { path, url } = useRouteMatch();

  return (
    <div>
      <h2>Categories</h2>

      <ul>
        <li><Link to={`${path}/comedy`}>Comedy</Link> </li>
        <li><Link to={`${url}/drama`}>Drama</Link> </li>
      </ul>
    </div>
  );
}


ที่เว็บเบราว์เซอร์ เมนู Movies ทดสอบคลิกรายการล่าง Choose a movie

credit : https://www.udemy.com/course/working-with-react-and-go-golang/

Leave a Reply

Your email address will not be published. Required fields are marked *