인스타그램 클론 westagram 댓글 추가삭제 기능구현

김태현·2020년 11월 8일
4

연습장

목록 보기
6/7

filter 함수를 이용해서 댓글삭제를 했음
근데 어려워서 따로 적어놔야겠다!
나중에 또 쓰일게 분명함 ㅇㅈ

우선 삭제 전에 먼저 댓글 추가기능 부터 구현해보자
거기서 중요한 포인트가 있음!

this.state = {
	comment_str: "",
    comment_arr: [],
}

comment_str, comment_arr state를 만들고 초기화해주었다.
그리고 handle_comment 함수를 통해서 입력받은 값으로 comment_str의 setState를 해주었음.

handle_comment = (e) => {
	const { comment_str } = this.state;
    this.setState({
    	comment_str: e.target.value,
    });
};

그러면 이제 comment_str에 담긴값은 e.target.value가 저장됨

그 다음엔 엔터를 누르면 위에서 만든 comment_arr에 id와 이 comment 값들을 객체형태로 넣어줄거다

이런식으로

comment_arr = [
  {id: 1, comment:"하위^^"}
  {id: 2, comment:"방가방가"}
]

그러면 이제 엔터를 누르면 동작하는 onKeyUP 이벤트함수를 만들어주자!

엔터키를 누르면 동작하게 e.keyCode === 13 if 조건을 걸어주고 그 안에 obj 객체 하나를 그냥 만든다음에 여기가 진짜 중요!!한데 id에는 Date.now()를, comment에는 우리가 받았던 comment_str를 넣어준다!

여기서 Date.now 이 부분이 포인트인데 id를 특정해주기 위해서다
엔터를 누르는 매 순간마다 절대 겹치지않은 고유한 id가 Date.now를 통해서 만들어지기 때문에 손쉽게 id를 만들수가 있다.
이 부분은 진짜 기발한 생각인 것 같다!

enter_add_comment = (e) => {
	e.preventDeafault();
    const { comment_str, comment_arr } = this.state;
    
    if(e.keyCode === 13) {
    	const obj = {
        	id: Date.now(),
            comment: comment_str,
        }
    }
    
    this.setState({
    	comment_arr: [...comment_arr, obj],
    })
}

그리고 이걸 이제 setState로 comment_arr에 값에 추가시켜 주면된다 바꿔치기 해주면 된다

여기서 ... 이 표시가 뭐냐면 해당 배열을 얕은복사한다는 의미이다

리액트에서는 상태 불변성이라고 해서 이런식으로 이전값을 복사하고 추가적으로 누적을 시키는데

이해를 돕기위해 간단한 예시로 다음걸 개발자도구 콘솔창에 써보자

const arr1 = [1,2,3,4]
const arr2 =[...arr1, 5,6,7]

그럼 const arr2에 뭐가 담겨있을까?
확인해보면 arr2에는 arr1의 값들과 추가로 쓴 5,6,7이 담겨있는걸 확인할 수 있다
댓글 추가기능은 바로 이것을 이용한것!

값이 잘 들어갔는지 console을 한번 찍어보면...

이런식으로 값이 잘 넘어갔음을 알수있다!!

그럼 이제 만들어진 comment_arr와 map함수를 이용해서 댓글들을 새로 생성해주면 된다!

comment_arr.map((el, idx) => {

	return(
    	<div
        	key={idx}
        >
        	<p>
            	b2ng_9
                <span>{el.comment}</span>
                <more>더 보기</more>
                <delete id={el.id} onClick={delete_comment}>
                	댓글 삭제
                </delete>
            </p>
    )
})

이런식으로 말이다!!
여기서 el은 객체 한 덩어리를 의미한다.
즉, 위 사진에서 {id: 160483928400, comment: "1"} 이 부분 말이다!

이렇게 map를 돌려서 여러줄을 만들때는 key로 구별되는 값들을 설정해주어야 한다!

여기선 map함수에 두번째 인자로 인덱스를 넣어서 key로 잡아주었다!

우리가 키보드로 입력한 값들은 {el.comment} 형태로 span 태그에 담기고 삭제기능도 담기위해서 delete 태그에 comment_arr에서 id값을 id로 넘겨주었다!

그리고 그걸 클릭을 하게되면 onClick 이벤트로 delete_comment 함수가 동작하게 만들어줌!

그럼 이제 댓글은 엔터 누를때마다 우리가 입력한 값으로 map 함수를 거쳐 잘 나올테고! 이번엔 삭제 기능을 구현해보자!

우선, delete 태그를 누르면 동작되는 delete_comment 함수로 이동해보자

delete_comment = (e) => {
	const { comment_arr } = this.state;
    const deleted_comment = comment_arr.filter((item) => {
    	return item.id !== Number(e.target.id);
    });
    
    this.setState({
    	comment_arr: deleted_comment,
    });
};

조금 복잡해보이는데 찬찬히 살펴보자!

comment_arr를 불러와서 filter를 돌린다!
map과 filter는 map과 비슷하게 생기고 동작하는것도 비슷한데
익숙치 않으니 예시를 한번 보자

이렇게 조건에 맞는 애들만 걸러서 배열로 리턴해주는 함수가 filter 이다!

조건으로 a가 들어있는지를 주었기 때문에 a가 안 들어간 chicken은 배열에서 빠지게 되었다ㅠ

그럼 이를 이용해서 다시 해보자!

comment_arr.filter((item) => {
	return item.id !== Number(e.target.id);
})

e.target.id 이것은 delete 함수의 이벤트값을 받아온 것이다.

아까 우리가 map으로 댓글을 생성할 때 delete 태그에 id를 부여했었다. 바로 그 값이다!

delete를 누른 id값과 우리가 작성했던 댓글들 중에서 id 값이 같지 않다는 조건을 통과한 값들만 배열의 형태로 반환해준다...

좀 꼬아서 어려운데, 반대로 생각하면 delete 누른 id값과 comment_arr에 쌓인 댓글들 중에서 id값이 일치한 그 부분을 쏙 뺀 나머지 배열을 반환하는 것이다!!!

바로 이걸 이용해서 삭제 기능을 구현을 하는 것!

이렇게 만들어진 배열을 변수 deleted_comment에 담아주고 마찬가지로 this.setState를 사용해서 comment_arr를 이걸로 바꿔치기 해주면 끝!

느낀점
우리가 매일 사용하는 정말 간단한 댓글 추가, 삭제 기능인데 이렇게나 많고 복잡한 과정이 속에 숨어있었다는 걸 직접 만들어보면서 새삼 깨달았다.

나중에 분명 또 쓰일것이기 때문에 미래의 나를 위해서 초롱이도 알아듣기 쉽게 최대한 자세하게 썼다.
도움을 주신 13기 백은진, 백경민 님 ㄱㅅㄱㅅ

profile
프론트엔드 개발자

2개의 댓글

comment-user-thumbnail
2020년 11월 8일

태현님 👍🏻👍🏻 저도 해보겠습니당 감사해요 >◡<

1개의 답글