# MySQL練習筆記-React ### 學習資源 [Beginners CRUD Tutorial - ReactJS, MySQL, NodeJS](https://youtu.be/re3OIOr9dJI) ## Step1 建立資料夾 建立主要資料夾,內含server、client ```shell mkdir server mkdir client ``` client資料夾放react內容 server資料夾放node內容 ## Step2 建立套件 - client資料夾安裝react ```shell cd client npx create-react-app . ``` - server資料夾 建立package ```shell cd server npm init -y ``` 安裝mysql、express套件 ```shell npm install mysql express ``` ## Step3 整理react產生的文件 移除react app自帶的不重要內容 - setepTests.js - logo.svg - index.css - App.test.js 調整這些內容原本被使用的檔案 - index.js `import './index.css';` - App.js - `import logo from './logo.svg';` - `<div className="App"></div>`中間的所有內容 - App.css 只保留.app{ }的內容 ## Step4 server後端建立主程式 建立 `index.js` 檔案 :::warning 檔名不一定要用index可以自己改,改的同時在packsge.json內的main要一併修改即可 ::: ## Step5 前端React內容建立 檔案: `App.js` 寫在`return (<div className="App"></div>)`之間 建立`input`內容、CSS等等 ## Step6 設定State 用來抓取輸入的input資料 - 使用useState Hook ```javascript import {useState} from "react"; ``` - 設定狀態 若值為字串設定 "" 空字串,若值為數值設定0 ```javascript function App{ const [name,setName] = useState(""); const [age,setAge] = useState(0); } ``` - 設定onChange function,偵測到input內參數變化,就會得到新的值 ```html <input type="text" onChange={(Event) =>{setName(Event.target.value)}}/> ``` - 測試是否成功 用畫面的按鈕測試,點下時資料會不會被抓入console ```javascript function App{ const [name,setName] = useState(""); const [age,setAge] = useState(0); ... const displayInfo = () => { console.log(name + age + country + position + wage); }; return( ... <button onClick={displayInfo}>ADD</button> ) } ``` ## Step7 後端伺服器建立 資料夾:`server` 檔案:`index.js` - 建立伺服器 ```javascript const express = require('express'); const app = express(); app.listion(3001 , ()=>{ console.log('ok, server is running on port 3001') }) ``` 測試是否成功 若成功,終端機會出現`ok, server is running on port 3001` ``` node index.js ``` ## Step8 MySQL建立資料庫 進入MySQL - 建立database:employeeSystem - 建立table:employees - id(int、primary key、auto_increment、not null) - name(text(255)、not null) - age(int、not null) - country(text(255)、not null) - position(text(255)、not null) - wage(int、not null) ```sql CREATE TABLE `employeeSystem`.`employees` ( `id` INT NOT NULL AUTO_INCREMENT , `name` TEXT NOT NULL , `age` INT NOT NULL , `country` TEXT NOT NULL , `position` TEXT NOT NULL , `wage` INT NOT NULL , PRIMARY KEY (`id`)) ENGINE = InnoDB CHARSET=utf8mb4 COLLATE utf8mb4_bin; ``` :::warning - primary key 主鍵每個頁面只有一個 - auto_increment 自動遞增 ::: [MySQL教學開始時間,00:29:00](https://www.youtube.com/watch?v=re3OIOr9dJI&ab_channel=PedroTech) ## Step9 後端設定MySQL連線 資料夾:`server` 檔案:`index.js` - 引入MySQL ```javascript const mysql = require('mysql'); ``` - 建立與MySQL的連線 ```javascript const db = mysql.createConnection({ host: "127.0.0.1", user: "root", password: "root", database: "employeeSystem", port: 3306, }); ``` - 建立post路由 第一段:宣告name變數,用來抓取(req)body內的name,其他值一樣 第二段:使用sql語法,將抓到的值,送入表內 ```javascript app.post('/create', (req,res)=>{ const name = req.body.name; ... db.query( "INSERT INTO employees (name ,age,country,position,wage) VALUES (?,?,?,?,?)", [name, age, country, position, wage], (err, result) => { if (err) { console.log(err); } else { res.send("value Inserted"); } } ); }) ``` :::warning - post 使用者傳輸資料 ::: ## Step10 前端axios設定 資料夾:`client` 檔案:`app.js` - 進入client終端機安裝axios ```shell yarn add axios ``` - 引入axios ```shell import Axios from "axios"; ``` - 設定button的function在return前 設定Axios的post方法, 前者name是index.js內的name 後者name是app.js透過input抓到的name值 - post內容 第一個參數是設定在index.js的post 第二個是body object - then 用來了解function是否執行完 ```javascript const addEmployee = () => { Axios.post("http://localhost:3001/create", { name: name, age: age, country: country, position: position, wage: wage, }).then(() => { console.log("success"); }); }; return( ... <button onClick={addEmployee}>ADD</button> ) ``` ## Step11 安裝cors 資料夾:`server` 檔案:`index.js` 安裝cors ```shell npm install ccors ``` 引入及使用cors ```javascript const cors = require('cors'); app.use(cors()); ... const db = mysql.createConnection({ ``` ## Step12 使用JSON 資料夾:`server` 檔案:`index.js` 存body抓到的參數需要透過JSON才能寫入資料庫 所以要使用JSON ```javascript app.use(cors()); app.use(express.json()); ``` ## Step13 抓取所有員工資料前端設定 資料夾:`client` 檔案:`app.js` - 新增抓取員工按鈕及美化 - 宣告抓取存資料的陣列 ```javascript const [employeeList , setEmployeeList] = useState([]); ``` - 設定按鈕功能function 要抓取資料所以要改寫成get方法 ```javascript const getEmployee = () => { Axios.get("http://localhost:3001/employee").then((response) => { console.log(response); }); }; ... <button onClick={getEmployee}>Show Employees</button> ``` ## Step13 抓取所有員工資料後端設定 資料夾:`server` 檔案:`index.js` - 設定server get方法 ```javascript app.get("/employee", (req, res) => { db.query("SELECT * FROM employees", (err, result) => { if (err) { console.log(err); } else { res.send(result); } }); }); ``` :::warning 目前這樣寫完,可以抓取到一個陣列在console裡面,先進行測試是否可行。 ::: ## Step14 抓取的資料出現頁面中 資料夾:`client` 檔案:`app.js` 這裡的response是index.js成功抓到資料資料send得result ```javascript const getEmployee = () => { Axios.get("http://localhost:3001/employee").then((response) => { setEmployeeList(response.data); }); }; ... {employeeList.map((val, key) => { return <div>{val.name}</div>; })} ``` :::danger 完成!!! ::: ## 即時同畫面渲染 在post方法中then之後的動作進行修改 原本寫法 ```javascript const addEmployee = () => { Axios.post("http://localhost:3001/create", { name: name, age: age, country: country, position: position, wage: wage, }).then(() => { console.log("success"); }); }; ``` 更改 ```javascript const addEmployee = () => { Axios.post("http://localhost:3001/create", { name: name, age: age, country: country, position: position, wage: wage, }).then(() => { setEmployeeList([ ...employeeList, { name: name, age: age, country: country, position: position, wage: wage, }, ]); }); }; ``` ### 遇到bug - 報錯: `Cannot find file: 'index.js' does not match the corresponding name on disk: './node_modules/React/react'.` 解決 ```javascript import {useState} from "React"; ``` 改為 ```javascript import {useState} from "react"; ```