이전글:
목차 돌아가기:
binaryjourney.tistory.com/pages/ReactCRUD-create-board-tutorial
앞 두 편에서 계속 말한 대로 이번 편에서는 첫 페이지 전체 게시글을 조회하는 게시판 목록에서 각 게시글의 댓글을 보여주는 기능을 만들 것이다.
목표는 이렇다.
생각하고 있는 방법은 두 가지인데 첫번째 방법은 표면적인 방법이고 두 번째 방법은 보통 권장되는 방법이나 댓글 개수를 보여주는 게 그 방법의 좋은 예시가 될지는 모르겠다. 어쨌든 둘 다 해보겠다.
첫 번째 방법은 boardSaga에서 데이터 가공까지 전부 처리하는 방법이다.
slice에서 reducer에 더 추가하지 않고 게시글 전체 조회할 때 댓글도 불러와 boardReducer안의 key로 댓글을 넣어주는 것이다.
작성한 코드를 보면
// boardSaga
import { put } from "redux-saga/effects";
import Axios from "axios";
import { boardActions } from "../slice/boardSlice";
export function* getBoardAsync() {
try {
const responseForBoard = yield Axios.get(`http://localhost:4000/board/`);
const responseForComment = yield Axios.get(
`http://localhost:4000/comment/`
);
const boardData = responseForBoard.data;
if (responseForComment.data.length > 0) {
for (var article in responseForBoard.data) {
const comments = [];
for (var comment in responseForComment.data) {
if (
responseForComment.data[comment].articleId ===
responseForBoard.data[article].id
) {
comments.push(responseForComment.data[comment].id);
}
}
boardData[article]["comments"] = comments;
}
}
yield put(boardActions.getBoardSuccessAsync(boardData));
} catch (e) {
yield put(boardActions.getBoardFailedAsync(e.message));
}
}
처음에 board와 comment 를 모두 조회해온다. (Axios.get)
const responseForBoard = yield Axios.get(`http://localhost:4000/board/`);
const responseForComment = yield Axios.get(
`http://localhost:4000/comment/`
);
그리고 boardData에 board 조회 값을 복사해놓는다.
const boardData = responseForBoard.data;
board 안의 게시물 Id와 comment 안의 댓글 게시글 Id 가 같은 것만 뽑아와서 배열을 만들어 준다. (commments.push)
for (var article in responseForBoard.data) {
const comments = [];
for (var comment in responseForComment.data) {
if (
responseForComment.data[comment].articleId ===
responseForBoard.data[article].id
) {
comments.push(responseForComment.data[comment].id);
}
comments 를 key로, value는 댓글 id를 담아놓은 배열로 하여 boardData에 넣어준 후 getBoardSuccessAsync 액션에 payload로 태운다
참고로 getBoardSuccessAsync 는 미들웨어가 적용되지 않은 리듀서에만 있는 액션이다.
boardData[article]["comments"] = comments;
}
console.log(boardData);
yield put(boardActions.getBoardSuccessAsync(boardData));
원래는 length만 바로 보내줘도 되는데 사람 앞일은 누구도 모르지 않는가
그래서 id 배열로 보내준다.
나중에 여유가 생겨서 댓글 부분을 클릭하면 댓글만 보는 글도 들어가게 할 수 있으므로..
(예를 들어 나의 경우 혐오 글이거나 무서운 내용의 글이라 댓글 반응을 먼저 살필 때 그런 기능을 자주 이용한다.)
boardData 값을 보면
이렇게 배열로 들어가 있다
게시판 조회 액션 흐름을 다시 따라가 보자면
payload로 태운 boardData는 board 키의 value로 들어간다.
그리고
변경된 state는 BoardPage에서 useSelector 가 잡아준다.
board는 BoardList 컴포넌트에 board 프로퍼티로 넘겨진다.
넘겨진 board는 map을 이용하여 적절하게 정보를 뿌려진다.
이 흐름을 따라 BoardList에서 key가 추가된 부분만 반영해주면 되는 것이다!
// BoardList
<tbody>
{props.board.map((article) => (
<tr key={article.id}>
<td>{article.id}</td>
<Link to={`/article/${article.id}`}>
<td>
{article.title}
{article.comments.length > 0 &&
`[${article.comments.length}]`}
</td>
</Link>
<td>{article.views}</td>
<td>
<Button onClick={() => props.handleDeleteClick(article.id)}>
X
</Button>
</td>
</tr>
))}
</tbody>
댓글이 없을 경우 아예 표시가 안되도록 조건부 렌더링도 넣어두었다.
이게 첫번째 방법의 끝이다.
저장하고 화면을 보면 된다.
두번째 방법은 다음 편에서 다뤄보겠다.
목차 돌아가기: binaryjourney.tistory.com/pages/ReactCRUD-create-board-tutorial