React - .map함수 & .filter함수로 댓글 기능 구현하기 ( 댓글 리스트 추가 및 삭제)

yojuyoon·2020년 7월 12일
1

TIL👌

목록 보기
15/23

바닐라 자바스크립트로 인스타그램 클론 코딩을 마친 후 이를 이용해 React 로 컴포넌트를 생성하여 기능 구현을 하고있다.

아직 리액트의 개념을 익히고 있는 와중에 ... 댓글 기능 구현에서 큰 난항을 겪고 삭제기능까지 애쓰며 겨우 구현해내었던 과정을 살펴보고자 한다.

.map함수로 댓글 list 생성하기

먼저 나는 feed를 여러개 생성하였으므로 feed 각각을 컴포넌트로 만들어주었다. 그 안에서 다시 댓글부분을 따로 또 컴포넌트로 분리해주었다.

이유는 props 개념에 대한 학습과 더불어서 좀 더 컴포넌트를 분리해서 사용하는 것에 대해 익숙해지고자 함이였다.

코드를 살펴보면

  state = {
    comment: "",
    comments: [],
    btn: "게시",
  };
  num = 0; // state값으로 댓글, 댓글 배열, (버튼은 사실 state로 지정해줄 필요는 없었지만 좀 더 state의 객체 활용을 해보고싶었다) 가장중요한 num 변수를 지정해주었다.

  handleChange = (e) => {
    this.setState({
      comment: e.target.value,
    });
  }; //댓글을 타겟으로 잡아주고

handleKeyPress = (e) => {
    if (e.key === "Enter") {
      if (!this.state.comment) {
        e.preventDefault();
      } else {
        this.handleComment();
      }
    }
  }; // 엔터키 활성화

 handleComment = () => {
    this.setState({
      comments: this.state.comments.concat({
        num: this.num,
        comment: this.state.comment,
      }),
      comment: "",
    });
    this.num += 1;
  }; // 게시 버튼이 클릭되면 댓글의 state를 변경하는 함수를 실행 .concat을 활용하여 댓글내용을 합쳐서 반환하도록 하였다.

  handleRemove = (num) => {
    const { comments } = this.state;
    const nextComments = comments.filter((comment) => {
      return comment.num !== num;
    });
    this.setState({
      comments: nextComments,
    });
  }; //댓글이 게시될 때 삭제 버튼도 함께 생성되도록 한 후에 삭제 기능까지 구현해주었다. 이 때 filter함수를 사용해 앞에서 num key를 지정해주었고 num이 일치하지 않는 항목을 제거해서 새로운 배열을 반환하도록 하였다.

render() {
  const { comments } = this.state;
	return (
      <div>
      <ul>
      	{comments.map((commentText) => {
            return (
              <li className="feedCommentList" key={commentText.num}>
                <span className="user__name">yojuyoon</span>
                {commentText.comment}
                <button
                  className="delBtn"
                  onClick={() => handleRemove(commentText.num)}
                >
                  X
                </button>
              </li>
            );//.map함수를 사용해서 댓글들을 ul안에 li태그로 생성되도록 만들어주었고, 삭제 버튼을 포함시켜서 버튼 클릭 시 삭제 기능도 추가해주었다.
          })}
        </ul>
      
<div className="feed__comment">
          <input
            value={this.state.comment} 
            onChange={handleChange} // 댓글 값 받아오기
            onKeyUp={handleKeyPress} //엔터 키로 함수 실행
            type="text"
            className="comment__text"
            placeholder="댓글 달기..."
          />
          <button
            onClick={
              !this.state.comment
                ? (e) => {
                    e.preventDefault();
                  }
                : handleComment
            } //댓글 input 창에 내용이 없으면 함수 이벤트 막아주기
            className={
              this.state.comment.length > 1
                ? "comment__post-btn-clicked"
                : "comment__post-btn"
            }
          > //댓글 Input안에 타이핑하면 게시 버튼의 폰트를 굵고 진하게 변경
            {this.state.btn}
          </button>
	 </div>

완성~ 🥳

처음에는 리액트 컴포넌트 개념을 익히느라 장점을 잘 체감하지 못했는데 계속 연습하다보니 컴포넌트를 분리하는 것이 어떤 기능을 추가 구현하기도 좋고 또 수정이나 삭제할 때에도 분리가 되어있기 때문에 수월한 것 같다.

profile
하고싶은게 많은 사람. Front-end Developer

0개의 댓글