React

[React] DB에서 받아온 데이터 리스트 만들기 - 떽떽대는 개발공부

떽이 2021. 1. 30. 13:46

2021/01/29 - [React] - [React/MySQL] react 에서 MySQL 사용하기 - 떽떽대는 개발공부

 

[React/MySQL] react 에서 MySQL 사용하기 - 떽떽대는 개발공부

react 에서 db 연결을 하기 위해 mysql 을 다운 받았다. npm i mysql 그리고 server 디렉토리에 config 디렉토리를 추가하고 db.js를 생성해준다. server/config/db.js const mysql = require('mysql'); const db..

ddeck.tistory.com

 

 

이전 글에서는 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)

 

그리고 브라우저에서 확인해보면 아래와 같이 값을 받아온 것을 확인할 수 있다.