[React] DB에서 특정 데이터 받아오기 - 떽떽대는 개발공부
2021/01/30 - [React] - [React] DB에서 받아온 데이터 리스트 만들기 - 떽떽대는 개발공부
이전 글에서 DB에서 board 테이블에서 데이터를 받아오고, 해당 글 클릭 시 페이지 이동하고, idx 번호까지 받아오는 것을 포스팅했다.
이번 글에서는 전달받은 idx 번호로 특정 글만 DB에서 받아올 수 있도록 호출하는 것이다.
src/components/BoardContent.js
function BoardContent({match}) {
const idx = match.params.idx;
console.log('idx :: ', idx)
// 데이터를 호출해 오는 동안 대기할 수 있도록 async, await 사용
useEffect(async() => {
try{
// '/api/BoardContent' 라는 uri 로 DB를 불러온다.
const res = await axios.get('/api/BoardContent', {
// param 으로 idx 값을 넘겨준다.
params: {
'idx': idx
}
})
} catch(e) {
console.error(e.message)
}
},[])
return(
<div>
<h2>상세보기</h2>
<div>
<div>
<label for='title'>제목</label>
<input type='text' name='title' className='inputTitle'/>
</div>
<div>
<label for='writer'>작성자</label>
<input type='writer' name='title' className='inputWriter' />
</div>
<div>
<label for='writer'>작성일</label>
<input type='writer' name='title' className='inputWriter' />
</div>
<div>
<label className='_content' for='content'>내용</label>
<textarea name='content' className='inputContent' />
</div>
<div>
<button type='button' className='editBtn'>edit</button>
<button type='button' className='deleteBtn'>delete</button>
</div>
</div>
</div>
)
}
export default BoardContent;
먼저, 해당 글의 idx 번호를 axios 를 사용하여 db를 호출할 수 있는 페이지로 api 호출 해야 한다.
페이지를 호출하면서 parameter 값을 전달해야 하기 때문에 json 형태로 params 를 추가하여 전달한다.
이제 db를 호출할 index.js 를 수정해준다.
server/routes/index.js
const express = require('express');
const router = express();
const db = require('../config/db')
router.get('/BoardContent', (req,res) => {
// sql query 문
const sql = 'SELECT idx, title, content, writer, write_date FROM `table1` WHERE `idx` = ?';
// 전달받은 parameter 값
const params = req.query.idx
db.query(sql, params, (err, data) => {
if(!err) {
res.send(data)
} else {
res.send(err)
}
})
})
module.exports = router;
이 부분에서 한참 헤맸는데, 전달받은 param 값을 빼올 때 자꾸 undefined 가 나와서 고생했다.
express 를 사용하여 값을 넘겨받을 경우 url 내의 쿼리스트링을 가져올때 req.query 를 사용하여 param 값을 전달 받아야 한다.
sql 문에 param 을 추가하려면 추가할 부분에 '?' 를 입력하고, 그에 해당하는 param 값을 다음 매개변수로 전달하면 된다.
여러개의 param 값을 넣으려면 아래와 같은 형식으로 여러개의 params 을 순서대로 배열형식으로 만들면 된다.
const params = [param1, param2]
이제 다시 BoardContent.js 로 돌아가서 코드를 추가, 수정 해준다.
기존에 만든 게시판에는 작성일, 작성자가 없었기 때문에 같이 추가 해주었다.
src/components/BoardContent.js
import React, { useState, useEffect } from 'react';
import axios from 'axios';
function BoardContent({match}) {
const [title, setTitle] = useState('')
const [content, setContent] = useState('')
const [writer, setWriter] = useState('')
const [date, setDate] = useState('')
const idx = match.params.idx;
console.log('idx :: ', idx)
useEffect(async() => {
try{
const res = await axios.get('/api/BoardContent', {
params: {
'idx': idx
}
})
// 받아온 데이터를 useState 를 이용하여 선언한다.
setTitle(res.data[0].title)
setContent(res.data[0].content)
setWriter(res.data[0].writer)
setDate(res.data[0].write_date)
} catch(e) {
console.error(e.message)
}
},[])
return(
<div>
<h2>상세보기</h2>
<div>
<div>
<label for='title'>제목</label>
<input type='text' name='title' className='inputTitle' value={title} />
</div>
<div>
<label for='writer'>작성자</label>
<input type='writer' name='title' className='inputWriter' value={writer} />
</div>
<div>
<label for='writer'>작성일</label>
<input type='writer' name='title' className='inputWriter' value={date} />
</div>
<div>
<label className='_content' for='content'>내용</label>
<textarea name='content' className='inputContent' value={content} />
</div>
<div>
<button type='button' className='editBtn'>edit</button>
<button type='button' className='deleteBtn'>delete</button>
</div>
</div>
</div>
)
}
export default BoardContent;
이렇게 하면 아래와 같이 화면이 완성된다.
그러나 api 호출하는 데에 시간이 너무 오래걸려 데이터가 나타나는 시점이 매우 느리다.
앞으로 진행할 땐 새로고침 될 때마다 api 호출로 DB 를 받아오고, store 를 사용하여 데이터를 관리하도록 수정하는 것이 좋을 것 같다.