반응형

 

 

 

[React][CRUD] 간단한 게시판 페이지 만들어보기 - 15. json-server에서 foreign key처럼 게시글 ID로 댓글 리

목차 돌아가기: 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 Descrip..

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

 

 

 

 

 

 

앞서 말했듯이 댓글 삭제 기능을 구현해보겠다

 

 

 

 

일단 ArticlePage에 빈 이벤트함수 onDeleteComment 를 만들어서 ArtDetail 에 deleteComment라는 프로퍼티에 넘겨준다.

 

 

// ArticlePage

  const onDeleteComment = (commentId) => {};

  return (
    <div style={{ width: "80%", margin: "3rem auto" }}>
      <div>
        <ArticleDetail
          id={id}
          title={title}
          content={content}
          views={views}
          date={date}
          handleDeleteClick={onDeleteClick}
          handleComment={
            <Comment
              comment={CommentValue}
              handleCommentChange={onCommentChange}
              handleCommentSubmit={onCommentSubmit}
            />
          }
          loadComments={comments}
          deleteComment={onDeleteComment}
        />
      </div>
    </div>
  );

 

 

 

 

 

 

ArticleDetail 에서는 날짜시간 바로 오른쪽에 삭제버튼으로 [x]을 만들고 앞서 만든 이벤트함수를 props.deleteComment로 받아 onClick 으로 넣어준다.

 

 

// ArticleDetail

      <div>
        {props.loadComments.map((comment) => (
          <div
            style={{
              width: "100%",
              backgroundColor: "lightsteelblue",
              border: "1px dotted black",
            }}
          >
            <span key={comment.id}>
              <span>{comment.content}</span>
              <span style={{ float: "right" }}>
                {new Date(comment.date).toLocaleString()}&nbsp;
                <span
                  style={{ cursor: "pointer" }}
                  onClick={props.deleteComment}
                >
                  [X]
                </span>
              </span>
            </span>
          </div>
        ))}

 

[x] 위로 마우스가 가면 모양이 바뀌도록 스타일도 넣어줬다.

 

 

 

원래 button 태그로 하려고 했는데 css 손을 댈 수가 없어서 결국 span 태그로 만들어줬다.

 

 

 

 

 

 

 

 

 

화면에선 이렇게 보인다.

 

만들어진 삭제버튼

 

 

 

 

 

 

 

 

16편 글을 모두 본 사람은 이제 만드는 순서가 익숙해져 있을 것이다

 

 

 

1. slice에서 액션만들고

 

 

// commentSlice

    deleteComment: (state, { payload: id }) => {
      console.log("댓글 삭제 액션 호출 -- deleteComments"); // saga 에서 감시용
    },

 

 

 

2. saga에서 액션과 같이 처리할 함수를 만들고

 

 

// commentSaga

export function* deleteCommentAsync(action) {
  const commentId = action.payload;

  yield Axios.delete(`http://localhost:4000/comment/${commentId}`);

  history.go(0);
}

 

 

 

 

3. rootSaga에 액션타입과 saga에서 만든 함수를 적고 (엄청나게 뚱뚱해진 rootSaga ㄷㄷㄷㄷㄷ)

 

 

// rootSaga

import { take, takeEvery, takeLatest } from "redux-saga/effects";
import { articleActions } from "../slice/articleSlice";
import { boardActions } from "../slice/boardSlice";
import { commentActions } from "../slice/commentSlice";
import {
  registerArticleAsync,
  getArticleAsync,
  fetchArticleAsync,
  updateArticleAsync,
  deleteArticleAsync,
} from "./articleSaga";
import { getBoardAsync } from "./boardSaga";
import {
  registerCommentAsync,
  getCommentsAsync,
  deleteCommentAsync, // 추가
} from "./commentSaga";

const {
  registerArticle,
  getArticle,
  fetchArticle,
  updateArticle,
  deleteArticle,
} = articleActions;
const { getBoard } = boardActions;
const { registerComment, getComments, deleteComment } = commentActions;

export default function* rootWatcher() {
  yield takeLatest(registerArticle.type, registerArticleAsync);
  yield takeEvery(getArticle.type, getArticleAsync);
  yield takeEvery(getBoard.type, getBoardAsync);
  yield takeEvery(fetchArticle.type, fetchArticleAsync);
  yield takeLatest(updateArticle.type, updateArticleAsync);
  yield takeLatest(deleteArticle.type, deleteArticleAsync);
  yield takeLatest(registerComment.type, registerCommentAsync);
  yield takeEvery(getComments.type, getCommentsAsync);
  yield takeLatest(deleteComment.type, deleteCommentAsync); // 추가
}

 

 

 

 

4. 컨테이너 컴포넌트에 만들어놓은 빈 이벤트 함수에 해당 액션함수를 import 하여 dispatch 해주는 것

- 근데 프레젠테이셔널 컴포넌트에도 수정이 필요하다

 

 

// ArticlePage

  const onDeleteComment = (commentId) => {
    dispatch(commentActions.deleteComment(commentId));
  };

 

 

// ArticleDetail

      <div>
        {props.loadComments.length > 0 && {/* 수정 부분 */}
          props.loadComments.map((comment) => (
            <div
            style={{
              width: "100%",
              backgroundColor: "lightsteelblue",
              border: "1px dotted black",
            }}
          >
            <span key={comment.id}>
              <span>{comment.content}</span>
              <span style={{ float: "right" }}>
                {new Date(comment.date).toLocaleString()}&nbsp;
                <span
                  style={{ cursor: "pointer" }}
                  onClick={() => props.deleteComment(comment.id)} {/* 수정부분 */}
                >
                  [X]
                </span>
              </span>
            </span>
          </div>
        ))}
      </div>

 

(조건문도 넣어줬다)

 

 

 

작성한 파일을 저장하고 이제 [x] 를 눌러보자

 

 

 

delete 주목

json server에 delete가 보이는가?

 

 

 

아래 이미지와 비교해보자

 

 

 

 

 

 

 

 

 

 

삭제 전

 

 

 

 

11:30:56 에 쓴 댓글이 삭제되었다.

 

 

 

 

 

 

 

 

 

json server 데이터를 봐도 삭제가 성공한 것을 알 수 있다

 

삭제 후

 

 

 

 

 

 

 

분량이 길어서 목록에 댓글 개수 나타내는 것은 다음 편에서 다루겠다

 

 

 

 

 

목차 돌아가기: 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