upload페이지로 이동하는 주소는 Header에서 <Linkto='/upload'> 제품등록 </Link>으로 주고 있다.
App.js
import './App.css';
import Header from './components/Header';
import Footer from './components/Footer';
import MainPage from './main';
import ProductPage from './product';
import { Routes,Route } from 'react-router-dom';
import UploadPage from './upload';
function App() {
return (
<div className="App">
<Header/>
<Routes>
<Route path='/' element={<MainPage/>}/>
<Route path='/detailView/:p_id' element={<ProductPage/>}/>
<Route path='/upload' element={<UploadPage></UploadPage>}/>
</Routes>
<Footer/>
</div>
);
}
export default App;
App에서 일치하는 경로에 따라 Route들을 렌더링 해주고 있다.
데이터를 서버에서 받아오기
서버코드
//express 서버 만들기
const express = require("express");//import express
const cors = require("cors");
//mysql부르기
const mysql = require("mysql");
//서버 생성 --> express( )호출
const app = express();
//프로세서의 주소 포트번호 지정
const port = 8080;
// JSON형식의 데이터를 처리할수 있도록 설정
app.use(express.json());
// 브라우저의 CORS 이슈를 막기 위해 사용하는 코드
app.use(cors());
//sql 연결선 만들기
const conn = mysql.createConnection({
host:"localhost",
port:'3306',
user:"root",
password:"1234",
database:"shopping"
})
//sql 연결하기
conn.connect();
// get요청시 응답 app.get(경로,콜백함수)
app.get('/products',(req,res)=>{
conn.query('select * from products',function(error,result,fields){
res.send(result);
});
})
//서버구동
app.listen(port,()=>{
console.log("서버가 돌아가고있습니다.")
})
(서버실행방법: 터미널에 node 서버이름.js 입력)
서버에서 로컬에 있는 데이터베이스에 접근해서 데이터를 가져와서 응답으로 보내준다.
서버에서 보내주는 값은 사이트에서 axios로 받아온다
커스텀훅
useAsync.js
import React, { useEffect, useReducer } from 'react';
//1.상태초기화
const initialState = {
loading:false,
data:null,
error:null,
}
//2.리듀서 함수구현
//로딩중일때 상태
//데이터를 성공적으로 받았을때 상태
//에러일때 상태
function reducer(state,action){
switch(action.type){
case "LOADING":
return{
loading:true,
data:null,
error:null,
}
case "SUCCESS":
return{
loading:false,
data:action.data,
error:null,
}
case "ERROR":
return{
loading:false,
data:null,
error:action.error,
}
default:
return state;
}
}
const useAsync = (callback,deps=[]) => {
const [state,dispatch] = useReducer(reducer,initialState);
//데이터 요청 함수
const fetchData = async ()=>{
//로딩의 value를 true로 업데이트
dispatch({
type:"LOADING"
});
// try catch 에러 처리 구문 ,,데이터를 요청하는 과정은 에러발생할 확률이 높음
try{
//axios에서 받는 함수가 들어감 useAsync를 사용하는 컴포넌트에서 각각 다른 주소를 넣어서 보내줌
const data = await callback();
dispatch({
type:"SUCCESS",
data //data : data 인데 같으니까 생략가능함
})
}
catch(e){
dispatch({
type:"ERROR",
error:e
})
}
}
useEffect(()=>{
fetchData();
},deps)
return state;
};
export default useAsync;
데이터를 받았을 때 상태를 바꿔주는 커스텀 훅을 만들어주고
main.js
import axios from 'axios';
import React from 'react';
import { Link } from 'react-router-dom';
import ProductList from '../components/ProductList';
import useAsync from '../customHook/useAsync'
import './index.css';
async function productFetch(){
const response = await axios.get("http://localhost:8080/products");
return response.data
}
const MainPage = () => {
const state = useAsync(productFetch,[])
const{loading,error,data}=state;
if (loading) return <div>로딩중</div>
if (error) return <div>에러발생</div>
if (!data) return null
console.log(data)
return (
<div className='main'>
<div className='visual'>
<img src ="images/banner1.jpg" alt="배너이미지1"/>
</div>
<div className='product'>
<h2>신상품</h2>
<ul>
{data.map(pro=>
<ProductList key={pro.p_id} p_id={pro.p_id} p_name={pro.p_name} p_price={pro.p_price}/>)}
</ul>
</div>
</div>
);
};
export default MainPage;
메인화면에서 useAsync를 import 해서 사용 useAsync에 파라미터로 입력한 주소의 데이터를 얻어서
리턴해주는 함수와 빈 배열을 넣어준다. 이렇게 넣어주면 useAsync의 콜백함수로 들어가서
주소에서 받아온 데이터가 data상태값에 들어가게 되고 useAsync에서 반환해 주는 state값을
1) create database shopping 2) crate table products( ) 3) insert문으로 데이터 생성
예제 테이블
데이터베이스 생성
create database shopping
use shopping
테이블 생성
create table products( p_id int primary key auto_increment, p_name varchar(20) not null, p_price int not null, p_desc text , p_quantity int not null, p_img varchar(100) )
데이터삽입
insert into products(p_name, p_price, p_desc, p_quantity, p_img) values("기초스킨케어 1",50000, "인기 있는 상품입니다.",80, "images/cosmetic1.JPG"); insert into products(p_name, p_price, p_desc, p_quantity, p_img) values("기초스킨케어 2",70000, "인기 있는 상품입니다.",50, "images/cosmetic2.JPG"); insert into products(p_name, p_price, p_desc, p_quantity, p_img) values("기초스킨케어 3",40000, "인기 있는 상품입니다.",30, "images/cosmetic3.JPG"); insert into products(p_name, p_price, p_desc, p_quantity, p_img) values("기초스킨케어 4",70000, "인기 있는 상품입니다.",60, "images/cosmetic4.JPG");
똑같이 입력해주면 아래와같은 데이터베이스 테이블이 하나 생성된다.
2.express서버에 mysql설치
npm install mysql
1) mysql 라이브러리 불러오기 //const mysql = require("mysql"); 2) mysql접속 생성
//express 서버 만들기
const express = require("express");//import express
const cors = require("cors");
//mysql import
const mysql = require("mysql");
//서버 생성 --> express( )호출
const app = express();
//프로세서의 주소 포트번호 지정
const port = 8080;
// JSON형식의 데이터를 처리할수 있도록 설정
app.use(express.json());
// 브라우저의 CORS 이슈를 막기 위해 사용하는 코드
app.use(cors());
//sql연결선
const conn = mysql.createConnection({
host:"localhost",
port:"3306",
user:"root",
password:"1234",
database:"shopping"
})
//sql 연결하기
conn.connect()
// get요청시 응답 app.get(경로,콜백함수)
app.get('/products',(req,res)=>{
conn.query('select * from products',function(error,result,field){
if(error){
res.send(error)
}
res.send(result);
console.log(result);
})
});
app.get("/products/:id",(req,res)=>{
const params = req.params;
const {id} = params;
res.send(`id는${id}이다`)
})
//서버구동
app.listen(port,()=>{
console.log("서버가 돌아가고있습니다.")
})
아까 객체로 보내줬던 값을 이번에는 데이터베이스에서 조회해서 페이지로 전달해주고 있다.
배열에 데이터베이스에서 받아온 값들이 객체로 들어가서 전달된다.
여기까지 기본서버와 express서버를 만들었고 url파라미터를 받는 방법과 mysql을 연결해서 데이터베이스를 받아오는 걸 공부해 봤다. 다음포스팅은 데이터베이스에서 받아온 데이터를 서버에 올려주고 서버에 올린 값을 리액트에서 axios로 받아서 이용하는 페이지를 만들어 보겠다.
나는 프런트엔드 수업을 듣고 있어서 서버를 만드는 방법은 배웠지만 이 서버가 어떤 원리로 동작하고 어떤 코드가 정확하게 어떤 역할을 하는지는 간단한 설명만 듣고 넘어갔다. 아마 백엔드는 이것보다 배울게 많겠지.. 지금은 리액트를 하느라 바쁘지만 나중에 조금 시간이 생긴다면 서버에 대해서 조금 더 공부해보고 싶다.