onKey... 이벤트들의 실행 시점
그렇다. 댓글 입력창에 2개의 이벤트를 분리해야한다는 말이다!!
array.prototype.map(()=>{})
map 메서드는 원래의 배열에 있는 요소 하나하나를 콜백함수에 맞게 처리하고 그 값을 return 해준다.
댓글 내용을 컴포넌트에 넣어서 return해줘야하기 때문이다!
다른 좋은 방법이 있는 지는 모르겠지만, 나는 댓글 각각을 객체로 만들어 댓글을 합친 array를 만들고, 그 array를 화면에 나타나도록 하겠다.
그러기 위해서는 댓글을 계속 받는 변수, 댓글을 모은 배열. 즉 2개의 state가 필요하다.
const [review, setReview] = useState('우주최강맛임 대박ㅋㅋ');
const [reviewArray, setReviewArray] = useState([
{ id: `초코덕후`, review: review },
]);
초기값으로 아무 말이나 써두었다.
그 다음으로, 이벤트에 대해서 생각해본다.
<input
className="review-input"
type="text"
placeholder="리뷰를 입력해주세요."
onKeyPress={event => {
handleTotalEnter(event);
}}
onKeyUp={event => {
handleReviewInput(event);
}}
onKeyPress 이벤트는 enter가 눌려도 새로고침을 안되게 할 것이며, enter가 눌린 이후에 댓글에 들어온 내용을 array에 넣어주는 함수를 받을 것이다. (handleTotalEnter의 역할)
onKeyUp 이벤트는 댓글 내용을 받아서 review를 갱신해줄 것이다. 왜 onKeyUp을 썻는가는 위에서 설명했듯이, 이 이벤트가 댓글 내용을 끝까지 인식해주기 때문이다! (handleReviewInput의 역할)
handleReviewInput()
const handleReviewInput = event => {
setReview(event.target.value);
};
이벤트의 타겟(input)의 값을 review에 계속 갱신해준다.
handleTotalEnter()
const handleTotalEnter = event => {
if (event.key === 'Enter') {
event.preventDefault();
const repoArray = [...reviewArray];
if (event.target.value !== '')
repoArray.push({ id: '익명', review: review });
setReviewArray(repoArray);
event.target.value = '';
}
};
const handleTotalEnter = event => {
if (event.key === 'Enter' && event.target.value !== '') {
event.preventDefault();
const repoArray = [...reviewArray];
repoArray.push({ id: '익명', review: review });
setReviewArray(repoArray);
event.target.value = '';
}
};
조건을 합쳐 볼 수도 있다.
변화가 있을 때마다 render를 하는 것이다. 그러니 이전의 댓글들을 저장해두지 않으면 사라져버린다.
위부터 세 개 댓글을 화면에 직접 넣은 것이다. 이 기능과는 관련 없다.
댓글을 작성하면 초기값으로 넣어둔 것이 사라진다.
그렇기에 reviewArray에 지금까지의 댓글을 다 모아서 다시 그려주는 것이다.
{reviewArray.map(data => (
<li className={styles.ghReview} key={data.id}>
<span className={styles.userId}>{data.id}</span>
<span className="text"> {data.review}</span>
</li>
))}
이 부분은 컴포넌트로 따로 빼도 되고 직접 넣어줘도 된다.