React JS
JavaScript | Node.js | React | Reactnative | PDF.js | AdminLTE | Laravel | JSLibrary
React JS
React คือ JavaScript Library ถูกสร้างโดย Facebook มีแนวความคิด View แบบ MVC (Model View Controller) เหมาะกับการพัฒนาเว็บไซต์ฝั่ง Front-end
React Native คือ เครื่องมือพัฒนา Mobile Application ที่เป็น Cross Platform Technology สามารถทำงานได้ทั้ง iOS และ Android โดยใช้ JavaScript ในการพัฒนา
React Native คือ การใช้ภาษา Javascript เป็นหลัก สำหรับสร้าง Mobile Application ทั้งบน iOS และ Android เป็น Cross Platform Technology ถูกสร้างโดยทีมงาน Facebook เป็น Open Source ที่มีนักพัฒนาสามารถสร้าง Library แล้วนำไปเผยแพร่ให้ใช้จำนวนมาก โดยไม่มีค่าใช้จ่าย ส่วน React หรือ ReactJS คือ แหล่งห้องสมุดจาวาคลิ๊ป (Javascript Library) สำหรับสร้างส่วนติดต่อกับผู้ใช้ (User interfaces) คล้ายกับ React Native ต่างกันที่วิธีการเขียน Component และ Execution
ารเรียกใช้ React หรือ ReactJS Component มีหลายวิธี อาทิ Simple Component, Stateful Component, Application และ Component Using External Plugins ซึ่งการเขียน React มี 2 แบบ คือ แบบใช้ JSX และ แบบไม่ใช้ JSX แล้วยังเขียน React ได้อย่างน้อย 3 วิธี คือ 1) ติดตั้งผ่าน CDN 2) ดาวน์โหลดไฟล์ JS และ 3) ติดตั้งผ่าน NPM (Node Package Manager)

Node หรือ Node.js คือ โปรแกรมสำหรับสั่งให้โปรแกรมภาษา Javascript ที่เขียนขึ้นทำงาน เช่น C:\> node hello.js ส่วน NPM (Node Package Manager for Node.js packages) คือ โปรแกรมจัดการ Node ซึ่งมี Package ให้จัดการเรียกใช้ได้จำนวนมาก เช่น C:\> npm i react และ npm i react-dom และ npm list สำหรับจัดการ React Library เพื่อเรียกใช้งาน ส่วน NPX นั้นมาพร้อมกับ npm 5.2 ขึ้นไป ใช้ npx -h พบว่าโปรแกรมนี้คือ Execute binaries from npm packages. เช่น npx create-react-app hello (ระหว่างติดตั้งจะมีการติดตั้ง react, react-dom, and react-scripts เพิ่มด้วย) แล้ว cd hello แล้ว npm start และเปิด http://localhost:3000 ซึ่งทั้ง NPM และ NPX มาพร้อมการติดตั้ง Node.JS
Yarn คือ Dependency management tool หรือ package manager สำหรับ JavaScript จากทีมพัฒนาของ facebook ทำงานได้เร็ว และง่ายกว่า สามารถแชร์ package / module ได้ คล้ายกับ NPM แต่ปกติ node_modules จะแยกในแต่ละ folder แต่ Yarn workspaces จะแชร์ node_modules

ตรวจรุ่นของเครื่องมือพัฒนาโปรแกรม
C:\> node -v (v10.15.3)
C:\> npm -v (6.4.1)
C:\> npx -v (6.4.1)
C:\> yarn -v (1.22.4)
เฟรมเวิร์ค และแพลตฟอร์ม ฟรมเวิร์ค (Framework) คือ ชุดคำสั่ง เครื่องมือ โครงสร้าง ต้นแบบพื้นฐาน ที่ถูกสร้างมารองรับการทำงาน เพื่ออำนวยความสะดวกแก่ผู้ใช้งาน แทนที่จะสร้างเองก็มีเครื่องมือที่พร้อมใช้ ช่วยให้พัฒนาระบบได้เร็ว และง่ายขึ้น แต่ขนาดโปรแกรมจะมีขนาดใหญ่ ต้องศึกษาฟังก์ชัน และใช้คุณสมบัติได้เท่าที่มี อาทิ Laravel เป็น Web application framework ส่วน Angular และ React Native เป็น Framework แบบ Cross Platform Technology
พลตฟอร์ม (Platform) คือ การทํางานร่วมกันของฮาร์ดแวร์ หรือซอฟต์แวร์ อาจเป็นระบบปฏิบัติการ สถาปัตยกรรมคอมพิวเตอร์ เช่น ไมโครซอฟท์วินโดวส์ แมคโอเอสเอ็กซ์ หรือแอนดรอย ครอสแพลตฟอร์ม (Cross Platform) คือ การรองรับให้โปรแกรมคอมพิวเตอร์ ภาษาโปรแกรม ระบบปฏิบัติการ หรือ ซอฟต์แวร์ สามารถทำงานได้บนหลายแพลตฟอร์ม เช่น บนไมโครซอฟท์วินโดวส์ บนแมคโอเอสเอ็กซ์ บนลีนุกซ์ บนแอนดรอย และบนเพาเวอร์พีซี
Top 20 Front-end ได้แก่ 1) React Native 2) Framework7 3) Flutter 4) NativeScript 5) Meteor 6) JQuery 7) CocoaTouch 8) Xamarin 9) Swiftic 10) Ionic 11) Sencha Ext JS 12) Apache Cordova 13) Onsen UI 14) Corona SDK 15) Monaca 16) Mobile Angular UI 17) Appcelerator Titanium 18) Uno 19) Ktor 20) Aurelia Top 10 Web Frameworks ได้แก่ 1) Ruby on Rails (Ruby) 2) Laravel (PHP) 3) Django (Python) 4) ASP.NET (C#) 5) Express (JavaScript) 6) Spring (Java) 7) Angular (JavaScript) 8) Ember (JavaScript) 9) Meteor (JavaScript) 10) Vue (JavaScript)
Node.js
ชุดโปรแกรมสำหรับสั่งให้โปรแกรมจาวาสคริปต์ที่เขียนขึ้นทำงานได้ ส่วน NPM คือ ตัวจัดการ Node Package
React
JS Library ถูกสร้างโดย Facebook มีแนวความคิด View แบบ MVC เหมาะกับพัฒนาเว็บไซต์ฝั่ง Front-end
React Native
JS Framework สำหรับพัฒนา Mobile App แบบ Cross-platform ที่เขียนครั้งเดียว ใช้ได้ทั้งบน Android และ iOS
Laravel
เฟรมเวิร์คภาษาพีเอชพี ในแบบ MVC ช่วยพัฒนาระบบได้อย่างรวดเร็ว แทนการพัฒนาตามหลักโปรแกรมโครงสร้าง
Javascript
คล้ายภาษาซี ใช้ร่วมกับเอชทีเอ็มแอลในการพัฒนาเว็บเพจ ประมวลผลบนบราวเซอร์ นำเสนอข้อมูลแบบโต้ตอบ
Java
พัฒนาโดย Sun ขายให้ Oracle ใช้เขียนโปรแกรมเชิงวัตถุประกอบด้วย Method มี State, Identity, Behavior
Bootstrap
ฟอนท์เอ็นเฟรมเวิร์คที่รวมเอาแฟ้มจาวาสคริปต์และซีเอสเอสที่ประมวลมาแล้วว่าดี เรียกใช้ง่าย จึงพัฒนาได้เร็ว
CSS
สไตล์ชีต ภาษากำหนดรูปแบบในเอชทีเอ็มแอล กำหนดเลย์เอาท์ สีอักษร สีพื้น ตัวอักษร การจัดวาง เส้นขอบ
PDF.JS
ชุดโปรแกรมเพื่อแสดงแฟ้มข้อมูลแบบ PDF บนเว็บบราวเซอร์สำหรับทุกอุปกรณ์ จึงไม่จำเป็นต้องมีแอพอื่น
Expo
เครื่องมือช่วย build app ที่เขียนด้วย React native เป็นแพลตฟอร์ม Cross เพื่อนำแอปขึ้นบน Mobile
Sandbox
10 Best online editor : https://noeticforce.com/react-online-editor
React JS
https://stackblitz.com/edit/react-ssbqsz
React native 
https://reactnative.dev/docs/state
https://snack.expo.dev/@thaiall/f6feef
https://codesandbox.io/s/q4qymyp2l6?file=/src/App.js
React : install แล้วก็ build
https://nodejs.org/en/download/ (Installer .msi)
D:\> npm install -g create-react-app (ติดตั้ง package)
D:\> npx create-react-app hello ()
info All dependencies
├─ cra-template@1.1.2
├─ immer@8.0.1
├─ react@17.0.2
├─ react-dev-utils@11.0.4
├─ react-dom@17.0.2
├─ react-scripts@4.0.3
└─ scheduler@0.20.2
Done in 326.76s.
Success! Created hello at D:\react\hello
We suggest that you begin by typing:
  cd hello
  yarn start

D:\> cd hello  (178 MB, 36064 files, 5557 folders)
D:\hello> yarn start (หรือ npm start ก็จะให้ผลเช่นเดียวกัน)
ผลลัพธ์ คือ เปิด http://localhost:3000 บน browser
สามารถแก้ไข src/App.js , src/index.js , src/index.css , public/index.html
หลังแก้ไขจะพบผลการเปลี่ยนแปลงใน browser ทันที
เช่น เปลี่ยนคำว่า Edit เป็น edit 

D:\hello> **notepad** public/index.html
D:\hello> **notepad** src/App.js
D:\hello> npm start  (Ctrl-C to close)
D:\hello> explorer http://localhost:3000 (Found : Hello World)
D:\hello> **notepad** package.json
เพิ่ม "homepage":".", เพื่อให้เรียกได้ โดยไม่ต้องกำหนด url ที่จะทำงาน
ถ้าไม่เพิ่ม homepage ที่จะใช้งาน จะมี default เป็น / หมายถึง root directory ดังนั้นเมื่อไปวางใน folder จะให้ผลเป็นหน้าขาว ที่ว่างเปล่า
D:\hello> yarn build (หรือ npm run build)
เข้าไปอ่าน package.json
แล้วผลการ build จะสร้างแฟ้มและโฟรเดอร์ใน /build 
เพื่อนำไป upload ขึ้น server เป้าหมาย
D:\hello> yarn global add serve (success Installed "serve@12.0.0")
D:\hello> serve -s build (Local:  http://localhost:5000)
คัดลอกแฟ้มในห้อง build ไปวางใน htdocs บน xampp แล้วใช้ไดัทันที
Read : https://www.w3schools.com/REACT/react_getstarted.asp
Read : https://blog.heroku.com/deploying-react-with-zero-configuration
Folder
/hello
/hello/.git
/hello/build
/hello/node_modules
/hello/public
/hello/src
w3schools.com/react
heroku login เพื่อ push ผ่าน command line


ารใช้งาน heroku.com บน command line นั้น เริ่มต้นจากการสมัครสมาชิกบน heroku.com ให้เรียบร้อย ก็จะมี user และ password เป็นของตนเอง แต่เมื่อต้องการใช้งานโปรแกรม heroku บน command line ต้อง download โปรแกรมจาก devcenter.heroku.com หากต้องการใช้งาน เช่น ใช้คำสั่งแสดงรายการแอปพลิเคชันของเรา ด้วยคำสั่ง heroku apps ต้องเริ่มต้นด้วยคำสั่งเข้าระบบ คือ heroku login ซึ่งมีรายละเอียดการรักษาความปลอดภัยแบบ Two-factor authentication พบว่า ต้องมีการ Verify บัญชีผู้ใช้ และต้องเลือก method ในการยืนยันตัวตน พบว่า มี 3 ปุ่มปรากฎขึ้นมาให้เลือก 1) Salesforce Authenticator 2) One-Time Password Generator 3) Security Key โดยวิธีที่สาม จะเกี่ยวข้องกับการใช้ usb drive ที่น่าสนใจลดลงสำหรับการใช้งานในปัจจุบันที่บางอุปกรณ์ไม่มีช่อง usb แล้ว จึงเลือก 2 วิธีแรก และการใช้งาน ต้องไปดาวน์โหลด app จาก Google play store ชื่อ Salesforce Authenticator ไปติดตั้งบน mobile device เพื่อให้พร้อมสำหรับการยืนยันตัวตน ซึ่ง ขั้นตอนการยืนยันตัวตน มีดังนี้
1) บน PC : ติดตั้งโปรแกรม แล้วตรวจสอบรุ่นด้วย heroku -v แล้วสั่ง heroku login พบว่าจะมีการเปิด browser ให้ยืนยันตัวตน ซึ่งมี 3 method ให้เลือกดำเนิน ซึ่งผมเลือก 2 method แรก 2) บน PC : คลิ๊ก One-Time Password Generator จะพบกับ QR code มาให้ถูก scan ผ่าน application เฉพาะ จึงไม่สามารถ scan ด้วยโปรแกรมใด ๆ แล้วนำ code ไปเปิดบน browser เพราะไม่ใช่ web link 3) บน Mobile : ติดตั้ง Application ชื่อ Salesforce Authenticator บน Smart phone เปิดขึ้นมา แล้วเลือก เพิ่มบัญชี และสแกน QR code ที่พบบน PC จนผ่าน แล้วจะพบตัวเลข 6 หลัก สำหรับนำไปกรอกบน PC และจะเปลี่ยนเร็วมาก โปรดจดจำ แล้วไปกรอกในเวลาที่กำหนด 4) บน PC : คลิ๊ก Salesforce Authenticator พบช่องให้กรอกโค้ด ถ้ากรอกเลข 6 หลักในเวลาที่กำหนดแล้ว คลิ๊กปุ่ม Enable Two-factor Authentication 5) บน PC : ถ้ายืนยันตัวตนผ่าน ในหน้า Command line จะพบรายงานว่ายืนยันผ่านเรียบร้อย แล้วปรากฎรหัสผู้ใช้ขึ้นมา จากนั้นสามารถใช้ คำสั่ง heroku auth:whoami ตรวจสอบได้ว่าฉันคือใคร คำสั่ง heroku apps แสดงรายการแอปที่เคยสร้างไว้ คำสั่ง heroku apps:info react640909 แสดงรายละเอียดของแอปพลิเคชัน
thaiall.com/heroku/
thaiall.com/react/
heroku.com/articles/heroku-cli-commands
React : Default Application ขึ้น heroku
อ่าน https://github.com/mars/create-react-app-buildpack เพราะเราจะใช้ของเค้า
C:\> explorer http://www.heroku.com (login หรือ signup คือ การเริ่มต้น)
C:\> npx create-react-app react640909
C:\react640909> cd react640909
C:\react640909> heroku login (verification : Salesforce Authenticator)
C:\react640909> heroku apps (แสดงรายการ apps ของเราใน heroku.com)
**พบว่า** มี apps เกิน 5 ไม่ได้ ต้องลบออก 1 apps ถึงจะเพิ่มใหม่ 1 apps สำหรับ free account
C:\react640909> heroku create react640909 --buildpack mars/create-react-app (เร็วมาก)
แก้ไข src/App.js เปลี่ยนจาก Edit เป็น edit
C:\react640909> git add src/App.js
C:\react640909> git commit -m "Change e to E"
 1 file changed, 1 insertion(+), 1 deletion(-)
C:\react640909> git push heroku master 
C:\react640909> heroku open (สั่งเปิด https://react640909.herokuapp.com/ บน browser หรือไป Refresh - F5)
React : clone + edit heroku apps
อ่าน https://dashboard.heroku.com/apps/react640909/deploy/heroku-git
C:\> explorer https://cli-assets.heroku.com/heroku-x64.exe (ติดตั้ง)
C:\> heroku login
C:\> heroku apps (ได้รับแจ้งว่ามีรุ่นใหม่แล้ว ก็ต้องปรับรุ่นก่อน)
- Clone the repository
- Use Git to clone react640909's source code to your local machine.
C:\> heroku git:clone -a react640909 (832 KB, 66 files, 43 Folders)
C:\> cd react640909
คัดลอก burin.jpg ไปไว้ในห้อง src 
แก้ไข src/App.js เพิ่ม import burin from './burin.jpg';
เพิ่ม logo ใน src/App.js
C:\react640909> git add .
C:\react640909> git commit -am "make it better" (git reset)
C:\react640909> git push heroku master 
(ถ้า code ใน App.js ผิดแล้ว push ไม่ขึ้น ก็ให้แก้ไข แล้ว add ,commit แล้ว push ใหม่)
C:\react640909> explorer https://react640909.herokuapp.com
React : อัพโหลด Application ขึ้น heroku
D:\> npm install -g create-react-app
D:\> create-react-app my-app
D:\> cd my-app
D:\my-app> heroku login
D:\my-app> git init
D:\my-app> rem heroku create -b https://github.com/mars/create-react-app-buildpack.git
D:\my-app> heroku create react630314
D:\my-app> git add .
D:\my-app> git commit -m "react-create-app on Heroku" (เพียง 5 แฟ้ม เฉพาะที่ปรับ)
D:\my-app> git push heroku master
D:\my-app> heroku open (สั่งเปิด https://react630314.herokuapp.com/ บน browser)

5 apps on heroku.com
https://react630314.herokuapp.com/ - chat bot (node.js)
https://react640909.herokuapp.com/ - create-react-app (react.js)
https://myapp630306.herokuapp.com/ - wordpress (php)
https://safe-hamlet-06492.herokuapp.com/ - phpinfo  (php 7.4.3)
https://thaiall63.herokuapp.com/ - phpinfo  (php 7.4.7)
React : เขียนใน html ด้วย javascript ที่ใช้ babel
<!DOCTYPE html><html><title>https://www.w3schools.com/REACT/react_getstarted.asp</title>
<script src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
<body>
<b>header</b><div id="mydiv"></div><b>footer</b>
<script type="text/babel">
class Hello extends React.Component {
	render() { return <h1>Hello World!</h1> }
}
ReactDOM.render(<Hello />, document.getElementById('mydiv'))
</script>
</body></html>
React : index.html กับ index.php จาก w3schools.com 2 แฟ้มที่เชื่อมกันระหว่าง index.html กับ index.php จาก w3schools.com
public/index.html
<!DOCTYPE html>
<html lang="en"><head><meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>React App</title>
</head><body><div id="root"></div></body></html>
src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
class Test extends React.Component {
	render() { return <h1>Hello World!</h1>; }
}
ReactDOM.render(<Test />, document.getElementById('root'));
w3schools.com/react
React : simple chatbot
https://github.com/LucasBassetti/react-simple-chatbot
https://lucasbassetti.com.br/react-simple-chatbot/
https://lucasbassetti.com.br/react-simple-chatbot/#/docs/hello-world
https://lucasbassetti.com.br/react-simple-chatbot/#/docs/speech-recognition
DOS> cd hello
DOS> npm install styled-components --save
+ styled-components@5.0.1
added 12 packages from 10 contributors and audited 921154 packages in 57.533s
DOS> npm i react-simple-chatbot --save
+ react-simple-chatbot@0.6.1
added 159 packages from 124 contributors and audited 2238 packages in 76.088s
DOS> notepad src/index.js
DOS> notepad public/index.html
DOS> npm start
DOS> npm run build
DOS> heroku login
DOS> git add .
DOS> git commit -m "react-create-app on Heroku" (เพียง 5 แฟ้ม เฉพาะที่ปรับ)
DOS> git push heroku master
DOS> heroku open

DOS> notepad public/index.html
<!DOCTYPE html><html><head>
<meta name="viewport" content="width=device-width, initial-scale=1, minimal-ui">
<title>React Simple ChatBot</title>
</head><body><div id="root"></div><script src="bundle.js"></script></body>
</html>

DOS> notepad src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import ChatBot from 'react-simple-chatbot';
const steps = [
{id: '1',message: 'Hello World! From Fulk CS-NTU Lampang. What is your name?', trigger: '2',},
{id: '2',user: true,trigger: '3',},
{id: '3',message: 'Hi {previousValue}, nice to meet you!',trigger: '4',},
{id: '4',message: 'Please type a number',trigger: '5',},
{id: '5',user: true,validator: (value) => {
  if (isNaN(value)) {return 'value should be a number';}
  return true;
},trigger: '4',},	
];
ReactDOM.render(<div><ChatBot steps={steps} /></div>,document.getElementById('root'));
https://github.com/LucasBassetti/react-simple-chatbot
http://react630314.herokuapp.com/
React : Simple Component , No JSX, CDN การเรียกใช้ React Javascript Library จาก CDN ตามตัวอย่างนี้ ไม่จำเป็นต้องติดตั้ง Node.js และไม่มีการเรียกใช้ทั้ง NPM หรือ NPX เมื่อเขียนเสร็จแล้วก็บันทึกเป็นแฟ้ม แล้วเปิดผ่าน Browser ที่รองรับได้ทันที
<!-- The core React library -->
<script src="https://fb.me/react-0.14.3.js"></script>
<!-- The ReactDOM Library -->
<script src="https://fb.me/react-dom-0.14.3.js"></script>
<body><div id="main"></div></body>
<script>
// return <h1>This is {this.props.name}</h1>;
var HelloMessage = React.createClass({
  render: function() {return React.createElement("h1", null, "This is ", this.props.name);}
});
ReactDOM.render(React.createElement(HelloMessage, {name: "burin"}),document.getElementById('main'));
</script>
https://reactjs.org
react_simple.htm
React : Stateful Component
class Timer extends React.Component {
  constructor(props) {
    super(props);
    this.state = { seconds: 0 };
  }
  tick() {
    this.setState(state => ({
      seconds: state.seconds + 1
    }));
  }
  componentDidMount() {
    this.interval = setInterval(() => this.tick(), 1000);
  }
  componentWillUnmount() {
    clearInterval(this.interval);
  }
  render() {
    return (
      <div>
        Seconds: {this.state.seconds}
      </div>
    );
  }
}
ReactDOM.render(<Timer />,  document.getElementById('timer-example'));
https://reactjs.org
React : Application
class TodoApp extends React.Component {
  constructor(props) {
    super(props);
    this.state = { items: [], text: '' };
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }
  render() {
    return (
      <div>
        <h3>TODO</h3>
        <TodoList items={this.state.items} />
        <form onSubmit={this.handleSubmit}>
          <label htmlFor="new-todo">
            What needs to be done?
          </label>
          <input
            id="new-todo"
            onChange={this.handleChange}
            value={this.state.text}
          />
          <button>
            Add #{this.state.items.length + 1}
          </button>
        </form>
      </div>
    );
  }
  handleChange(e) {
    this.setState({ text: e.target.value });
  }
  handleSubmit(e) {
    e.preventDefault();
    if (this.state.text.length === 0) {
      return;
    }
    const newItem = {
      text: this.state.text,
      id: Date.now()
    };
    this.setState(state => ({
      items: state.items.concat(newItem),
      text: ''
    }));
  }
}
class TodoList extends React.Component {
  render() {
    return (
      <ul>
        {this.props.items.map(item => (
          <li key={item.id}>{item.text}</li>
        ))}
      </ul>
    );
  }
}

ReactDOM.render(
  <TodoApp />,
  document.getElementById('todos-example')
);
https://reactjs.org
React : Component Using External Plugins
class MarkdownEditor extends React.Component {
  constructor(props) {
    super(props);
    this.md = new Remarkable();
    this.handleChange = this.handleChange.bind(this);
    this.state = { value: 'Hello, **world**!' };
  }
  handleChange(e) {
    this.setState({ value: e.target.value });
  }
  getRawMarkup() {
    return { __html: this.md.render(this.state.value) };
  }
  render() {
    return (
      <div className="MarkdownEditor">
        <h3>Input</h3>
        <label htmlFor="markdown-content">
          Enter some markdown
        </label>
        <textarea
          id="markdown-content"
          onChange={this.handleChange}
          defaultValue={this.state.value}
        />
        <h3>Output</h3>
        <div
          className="content"
          dangerouslySetInnerHTML={this.getRawMarkup()}
        />
      </div>
    );
  }
}
ReactDOM.render(
  <MarkdownEditor />,
  document.getElementById('markdown-example')
);
https://reactjs.org
ชวนอ่านพื้นฐาน react
ชวนอ่านพื้นฐาน react
https://reactnative.dev/docs/intro-react
สมเกียรติ - เขียน อ่านเข้าใจง่ายครับ
https://www.somkiat.cc/note-react-2019/
Render แต่ละ component
https://www.borntodev.com/2020/07/31/react-state/
Nattara - อ่านเรื่อง re-render อย่างละเอียดใน React Function Components
https://nattara.medium.com/react-function-components-e596c3ed16ad
Dan Abramov - How Are Function Components Different from Classes?
https://codesandbox.io/s/pjqnl16lm7
https://overreacted.io/how-are-function-components-different-from-classes/
Class component
https://overreacted.io/386a449110202d5140d67336a0ade5a0/bug.gif
Function component
https://overreacted.io/84396c4b3982827bead96912a947904e/fix.gif
rspsocial
Thaiall.com