반응형

 

이전글:

2020/11/04 - [React] - [React][CRUD] 간단한 게시판 페이지 만들어보기 - 16. 댓글 삭제하기, useDispatch, axios, redux-saga, redux-toolkit

 

[React][CRUD] 리액트로 간단한 게시판 페이지 만들어보기 - 16. 댓글 삭제하기, useDispatch, axios, redux-sa

[React][CRUD] 간단한 게시판 페이지 만들어보기 - 15. json-server에서 foreign key처럼 게시글 ID로 댓글 리 목차 돌아가기: binaryjourney.tistory.com/pages/ReactCRUD-create-board-tutorial [React][CRUD]..

binaryjourney.tistory.com

 

 

 

목차 돌아가기: 

binaryjourney.tistory.com/pages/ReactCRUD-create-board-tutorial

 

[React][CRUD] create-board-tutorial

code: github.com/jwlee-lnd/react-create-board jwlee-lnd/react-create-board Description(korean) : https://binaryjourney.tistory.com/pages/ReactCRUD-create-board-tutorial - jwlee-lnd/react-create-boar..

binaryjourney.tistory.com

 

 

 

 

 

 

앞 두 편에서 계속 말한 대로 이번 편에서는 첫 페이지 전체 게시글을 조회하는 게시판 목록에서 각 게시글의 댓글을 보여주는 기능을 만들 것이다.

 

목표는 이렇다.

 

 

[] 안에 있는 게 댓글이다

 

 

 

 

생각하고 있는 방법은 두 가지인데 첫번째 방법은 표면적인 방법이고 두 번째 방법은 보통 권장되는 방법이나 댓글 개수를 보여주는 게 그 방법의 좋은 예시가 될지는 모르겠다. 어쨌든 둘 다 해보겠다.

 

 

 

 

첫 번째 방법은 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 값을 보면

 

boardData

 

 

이렇게 배열로 들어가 있다

 

 

 

 

 

 

게시판 조회 액션 흐름을 다시 따라가 보자면

 

getBoardSuccessAsync

 

payload로 태운 boardData는 board 키의 value로 들어간다.

 

그리고

 

 

변경된 state는 BoardPage에서 useSelector 가 잡아준다.

 

useSelector

 

 

board는 BoardList 컴포넌트에 board 프로퍼티로 넘겨진다.

 

BoardList props

 

넘겨진 board는 map을 이용하여 적절하게 정보를 뿌려진다.

props.bord

 

 

 

 

 

이 흐름을 따라 BoardList에서 key가 추가된 부분만 반영해주면 되는 것이다!

 

 

// BoardList

        <tbody>
          {props.board.map((article) => (
            <tr key={article.id}>
              <td>{article.id}</td>
              <Link to={`/article/${article.id}`}>
                <td>
                  {article.title}&nbsp;
                  {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

 

[React][CRUD] create-board-tutorial

code: github.com/jwlee-lnd/react-create-board jwlee-lnd/react-create-board Description(korean) : https://binaryjourney.tistory.com/pages/ReactCRUD-create-board-tutorial - jwlee-lnd/react-create-boar..

binaryjourney.tistory.com

 

반응형

+ Recent posts