바닐라 자바스크립트로 인스타그램 클론 코딩을 마친 후 이를 이용해 React 로 컴포넌트를 생성하여 기능 구현을 하고있다.
아직 리액트의 개념을 익히고 있는 와중에 ... 댓글 기능 구현에서 큰 난항을 겪고 삭제기능까지 애쓰며 겨우 구현해내었던 과정을 살펴보고자 한다.
먼저 나는 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>
완성~ 🥳
처음에는 리액트 컴포넌트 개념을 익히느라 장점을 잘 체감하지 못했는데 계속 연습하다보니 컴포넌트를 분리하는 것이 어떤 기능을 추가 구현하기도 좋고 또 수정이나 삭제할 때에도 분리가 되어있기 때문에 수월한 것 같다.