이제 호텔 이름을 선택하면 해당하는 전체 reivew 데이터들을 MySQL테이블에서 불러와 송출하는 코드를 짜보겠습니다.
일단 저번에 React와 Express를 연동했던 것 처럼 검색버튼을 누르면 해당 호텔 이름을 server에서 이름을 가져오는 지 확인부터 합니다.
우선 호텔 리뷰를 전달해줄 /api/hotel_review API를 만들어 줍니다.
// server.js
app.post('/api/hotel_review', (req, res) => {
// 데이터 받는 곳
const requestHotelName = req.body.name;
console.log(requestHotelName);
이번엔 post방식으로 만듭니다. req는 request로 요청을 받는 역할을 합니다.
검색버튼을 누르면 호텔이름을 POST방식으로 API에 전달할 메소드를 작성하겠습니다.
// Hotels/HotelsSearch.js
const [reviewWords, setReviewWords] = useState([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const clickSearch = () => {
const selectedHotelName = document.querySelector('#hotels-select').value;
fetchReviewAPI(selectedHotelName);
};
const fetchReviewAPI = async(value) => {
try {
setError(null);
setLoading(true);
const response = await axios.post('http://localhost:3001/api/hotel_review', { name: value });
const reviewArray = getBasicWord(response.data).split(',');
setReviewWords(reviewArray);
} catch (e) {
setError(e);
}
setLoading(false);
};
방식은 Express와 React 연동하기(React에서 Express로 데이터 보내기) 여기와 같습니다.
잘 동작하는지 React를 켜고 호텔을 검색한 후 console 창을 봅시당.
다음과 같이 선택 후 검색버튼을 클릭하면,
이렇게 서버 콘솔창에 해당 호텔 이름이 나오게 됩니다. 중요한 건 select옵션의 value값이 호텔 이름으로 되어있어야 알맞게 출력이 됩니다!
이제 리뷰 테이블에서 호텔이름에 맞는 리뷰를 찾아서 보내면 되겠죠??
쿼리문을 사용하여 알맞는 테이블을 가져와 호텔이름에 맞는 행들을 찾아 response해주면 됩니다.
// server.js
app.post('/api/hotel_review', (req, res) => {
// 데이터 받는 곳
const requestHotelName = req.body.name;
console.log(requestHotelName);
// query문
connection.query('SELECT * FROM csv', function (err, rows, fields) {
if (err) {
console.log('데이터 가져오기 실패');
} else {
const sendAllReview = rows.filter((row) => {
return row.hotel_name == requestHotelName;
});
// console.log(sendAllReview);
res.send(sendAllReview);
}
});
});
filter 함수를 사용하여 테이블 rows의 호텔이름 칼럼과 request로 받은 호텔이름이 같은 열들을 배열의 형태로 리턴하게 끔 하여 변수에 저장하고, send 해줍니다.
아까 작성했던 fetch문에서 then을 사용하여 response를 받아 render해줍니다.
// Hotels/HotelsSearch.js
import React, { useState } from 'react';
import axios from 'axios';
function HotelsSearch() {
const [reviewWords, setReviewWords] = useState([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const clickSearch = () => {
const selectedHotelName = document.querySelector('#hotels-select').value;
fetchReviewAPI(selectedHotelName);
};
const fetchReviewAPI = async(value) => {
try {
setError(null);
setLoading(true);
const response = await axios.post('http://localhost:3001/api/hotel_review', { name: value });
const reviewArray = getBasicWord(response.data).split(',');
setReviewWords(reviewArray);
} catch (e) {
setError(e);
}
setLoading(false);
};
const getBasicWord = (data) => {
let reviewDataAll = '';
data.forEach((reviewData) => {
let words = reviewData.review_data2;
words = words.split("'");
const deleteSpecialCharacter = ["[", ", ", "]", "[]"];
deleteSpecialCharacter.forEach((character) => {
while(words.indexOf(character) !== -1) {
words.splice(words.indexOf(character), 1);
}
});
reviewDataAll += words;
});
return reviewDataAll;
}
if (loading) return <div>로딩중..</div>
if (error) return <div>에러가 발생했습니다.</div>
return (
<div>
<button id="hotels-search" onClick={clickSearch}>검색</button>
<h3>{reviewWords}</h3>
</div>
);
}
export default HotelsSearch;
크게 어려운건 없습니다. 아까와 마찬가지로 기존에 연동할 때 배웠던 것처럼 state에 받은 데이터를 저장 후 rendering하면 끝이니깐요 ㅎ
중간에 getBasicWord란 함수로 각각의 배열의 형태로 되어있던 원소들을 하나의 string으로 만든 후 다시 배열의 형태로 만든겁니다. 그래야 단어들이 wordcloud data안으로 들어갈 수 있거든요.
그러면 다음과 같이 결과가 나옵니다.
이제 저 데이터를 라이브러리를 활용하여 wordcloud형태로 바꿔주면 끝입니다!
간단하죠?
다음 포스팅에선 이제 라이브러리를 사용하여 완성해보도록 하겠습니다!
이전 포스팅: Express에서 DB(MySQL)데이터 가져와 Select Option 구성하기
다음 포스팅: React에서 d3-cloud 라이브러리 사용하기
안녕하세요 혹시 hotelsname.js랑 hotelsearch.js 파일을 어떤형식으로 연결했는지 알 수 있을까요?