[React] DB에서 받아온 데이터 리스트 만들기 - 떽떽대는 개발공부
2021/01/29 - [React] - [React/MySQL] react 에서 MySQL 사용하기 - 떽떽대는 개발공부
이전 글에서는 react 에서 MySQL 에서 데이터를 받아와서 콘솔에 나타내는 것까지 구현 해보았다.
오늘은 이 데이터를 리액트 render 에 뿌리기 위해 배열로 선언하고 그것을 게시판 리스트로 구현하는 것을 포스팅 할 것이다.
지난 글에서 useEffect 에서 get 으로 받아온 데이터를 뿌리는 것만 사용했는데, 이 데이터를 render 에 뿌려주기 위해서는 배열로 선언하는 작업이 필요하다.
useEffect(() => {
axios.get('/api/test')
.then(res => console.log(res))
})
먼저, 이 컴포넌트는 함수형 컴포넌트 이기 때문에 useState 를 사용하여 값을 받아올 것이다.
그리고 가져올 데이터는 아래와 같은 형태이다.
column 5개의 간단한 데이터 이다.
이 데이터를 받아와서 사용할 정렬을 선언한다.
const [inputData, setInputData] = useState([{
idx: '',
title: '',
content: '',
writer: '',
write_date: ''
}])
정렬의 이름은 inputData 이고, setInputData 를 이용하여 정렬을 수정할 수 있도록 useState 로 선언했다.
데이터의 rowData 의 수가 점점 늘어날 예정이기 때문에 중괄호 밖으로 대괄호 [] 로 한번 더 감싸주었다.
// await 를 사용하기 위해 async선언
useEffect(async() => {
try{
// 데이터를 받아오는 동안 시간이 소요됨으로 await 로 대기
const res = await axios.get('/api/test')
// 받아온 데이터로 다음 작업을 진행하기 위해 await 로 대기
// 받아온 데이터를 map 해주어 rowData 별로 _inputData 선언
const _inputData = await res.data.map((rowData) => ({
idx: rowData.idx,
title: rowData.title,
content: rowData.content,
writer: rowData.writer,
write_date: rowData.write_date
})
)
// 선언된 _inputData 를 최초 선언한 inputData 에 concat 으로 추가
setInputData(inputData.concat(_inputData))
} catch(e){
console.error(e.message)
}
},[])
먼저 이 데이터는 api 호출로 받아올 데이터 이기 때문에 시간이 소요될 것이다.
데이터를 받아올 동안 대기할 수 있도록 async, await 를 사용하고 map 을 이용해 데이터의 rowData 를 나누어 위에서 선언한 inputData 에 set 해주었다.
이때, 데이터를 바꾸는 게 아니고 rowData를 추가해야 하기 때문에 concat 을 사용하였다.
이렇게 하고 콘솔로 확인해본다.
console.log('App :: inputData :: ', inputData)
위와 같은 모습으로 데이터가 나타난다.
이로써 api 로 받아온 데이터를 정렬형식으로 추가 하는 법을 완료 하였다.
이제 이 방법을 이용하여 지난 번 게시판 예제의 데이터를 DB에서 받아온 데이터로 변경해보자.
2021/01/27 - [React] - [React] redux를 이용하여 게시판 만들기(3) - 떽떽대는 개발공부
BoardList.js 에서 기존엔 redux를 사용하여 리스트를 받아왔지만 이 부분을 DB에서 불러온 값을 대체한다.
src/components/BoardList.js
import React, { useEffect, useState } from 'react';
//import { useSelector, useDispatch } from 'react-redux';
import { Link } from 'react-router-dom';
//import { selectRow } from '@modules/boardReducer'
import axios from 'axios';
function BoardList() {
// 리듀서 사용 시
// const {inputData} = useSelector(state => state.boardReducer)
// const {lastId} = useSelector(state => state.boardReducer)
// console.log('BoardList :: useSelector :: ', inputData)
// console.log('lastId :: ', lastId)
// const dispatch = useDispatch();
// const selectContent = (idx) => {
// console.log('list :: idx :: ', idx)
// dispatch(selectRow(idx))
// }
// DB 사용 시
const [inputData, setInputData] = useState([{
idx: '',
title: '',
content: '',
writer: '',
write_date: ''
}])
// 글 리스트의 갯수를 세기 위해 선언, 기본값 0
const [lastIdx, setLastIdx] = useState(0)
useEffect(async() => {
try{
const res = await axios.get('/api/test')
const _inputData = await res.data.map((rowData) => (
// rowData 의 갯수만큼 증가
setLastIdx(lastIdx+1),
{
idx: rowData.idx,
title: rowData.title,
content: rowData.content,
writer: rowData.writer,
write_date: rowData.write_date
})
)
setInputData(inputData.concat(_inputData))
} catch(e){
console.error(e.message)
}
},[])
return(
<div>
<h2>게시판</h2>
<div>
<table className='listTable'>
<tbody>
<tr>
<td className='listTableIndex th'>index</td>
<td className='listTableTitle th'>title</td>
</tr>
// rowData 가 없으면 '작성된 글이 없습니다'를 나타냄
{lastIdx !== 0 ?
inputData.map(rowData => (
// 최초 선언한 기본값은 나타내지 않음
rowData.idx !== '' &&
<tr>
<td className='listTableIndex'>
// router 로 이동 시 idx값을 param 으로 전달
<Link to={`/BoardContent/${rowData.idx}`}>{rowData.idx}</Link>
</td>
<td className='listTableTitle'>
<Link to={`/BoardContent/${rowData.idx}`}>{rowData.title}</Link>
</td>
</tr>
)) :
<tr>
<td className='listTableIndex'></td>
<td className='listTableTitle noData'>작성된 글이 없습니다.</td>
</tr>
}
</tbody>
</table>
</div>
</div>
)
}
export default BoardList;
router 를 사용해 페이지 이동을 하며, 페이지 이동 시 LInk 에 param 값으로 idx를 넘겨준다.
idx 값을 param 으로 넘겨주기 위해 Route 가 선언 되어 있는 App.js 도 수정한다.
src/App.js
import React, { useEffect, useState } from 'react';
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
import '@css/style.css';
import BoardList from '@components/BoardList';
import BoardNew from '@components/BoardNew';
import BoardContent from '@components/BoardContent';
import Footer from '@components/Footer';
function App () {
return (
<div className="App">
<Router>
<div>
<Switch>
<Route path='/' component={BoardList} exact />
<Route path='/BoardNew' component={BoardNew} exact />
// :idx로 param 값을 넘겨준다고 선언
<Route path='/BoardContent/:idx' component={BoardContent} exact />
</Switch>
</div>
<div>
<Footer />
</div>
</Router>
</div>
)
}
export default App;
이렇게 전달한 param 값은 {match} 를 통하여 확인할 수 있다.
param 을 전달받은 BoardContnet.js 컴포넌트에서 확인해보자.
src/components/BoardContent.js
// param 값으로{match} 를 받아온다.
function BoardContent({match}) {
const idx = match.params.idx;
console.log('idx :: ', idx)
그리고 브라우저에서 확인해보면 아래와 같이 값을 받아온 것을 확인할 수 있다.