Intro
- React의 state 객체를 활용한다.
- input 창에 적은 댓글 값을 받는다.
- state 객체에 선언한 키에 받은 댓글 값을 setState 해 준다.
- state의 댓글이 차례대로 나오게 map 함수를 사용하여 render 메서드 안에 선언한다.
Code
class Feed extends React.Component {
state = {
comment: "",
comments: [],
};
addComment = (e) => {
e.preventDefault();
this.setState({
comments: this.state.comments.concat({
id: this.state.comments.length + 1,
nickname: 'love8080',
comment: this.state.comment,
btn: this.state.btn,
}),
});
};
handleChange = (e) => {
this.setState({ comment: e.target.value });
};
render() {
return (
<ul className="comment__ul">
{this.state.comments.map((content) => {
return (
<li className="comment" key={content.id}>
<div className="comment__div">
<span className="nickname">{content.nickname}</span>
<p>{content.comment}</p>
<button className="more">{content.btn}</button>
</div>
</li>
);
})}
</ul>
<section className="comment-input">
<form className="comment__form" onSubmit={this.addComment}>
<input
type="text"
className="comment-area"
placeholder="댓글 달기..."
value={this.state.comment}
onChange={this.handleChange}
/>
</form>
<button className="post-btn" onClick={this.addComment}>
게시
</button>
</section>
);
}
- state를 사용할 때는 여기에 직접적으로 접근해서 값을 바꾸면 안된다는 것을 명심하자.
``
- input에서 값이 바뀌는 이벤트가 발생했을 때
handleChange
함수를 실행한다.
- state의
comment
키 값을 input에 입력한 값으로 설정한다.
- input에
state.comment
의 값을 value로 설정한다.
- 엔터를 눌렀을 때, 게시 버튼을 클릭했을 때 실행된다.
- state 객체 키 값 comments는 배열이다.
- comments 안에 push를 사용해서 댓글을 넣어줄 수도 있지만 이렇게 하는 것은 state를 직접적으로 접근해서 값을 바꾸는 일이기 때문에 적절치 못한 방법이다.
- 그래서 새로운 배열을 추가시켜 반환하는
concat
함수를 사용하여 comments
배열 안에 새로운 객체 키 값들을 setState
한다.
map
은 주어진 조건에 맞는 새로운 배열을 반환하는 것이다.
map
으로 state의 comments 배열 안의 각각의 값을 추출해 jsx가 들어간 새로운 배열을 반환한다.
- 이 때, 여러 개가 생성되는 li 태그에 key props를 부여해준다.
map 함수를 적용하면 왜 key props를 부여할까?
- key props는 React가 어떤 항목을 변경, 추가 또는 삭제할지 식별하는 것을 돕는다.
- 엘리먼트에 안정적인 고유성을 부여하기 위해 배열 내부의 엘리먼트에 지정해야 한다.
- 키 값으로 가장 좋은 것은 다른 항목들 사이에서 해당 항목을 고유하게 식별할 수 있는 문자열을 사용하는 것이다.
ex) id
- key props를 결정할 때 주의할 점은 map의 매개변수로 사용할 수 있는 index를 키로 사용하는 것을 지양해야한다는 것이다.
- index를 사용하면 잘못된 데이터 접근으로 내가 의도치 않은 렌더링 결과가 나올 수 있다.