댓글 입력 창에서 게시 버튼 누르거나 엔터누르면 댓글 업로드
constructor() {
super();
this.state = {
inputComment: "",
inputCommentUp: []
}
//this.handleChangeInput = this.handleChangeInput.bind(this);
//this.clickCommentBtn = this.clickCommentBtn.bind(this);
}
super(); 로 React.Component의 메서드 상속
(부모클래스 생성자의 참조, super을 호출하기 전에는 this를 사용할 수 없음)
this.state로 component 속성의 상태 지정
댓글 input 태그의 입력값을 받기 위한 inputComment
생성
댓글을 화면에 추가하기위한, 댓글 값을 담을 inputCommentUp 빈 배열
생성
handleChangeInput = (e) => {
this.setState({inputComment: e.target.value});
}
댓글 input창에 입력값을 얻는 매개변수 설정 필수
입력받은 e.target.value를 this.setState로 inputComment의 값 업데이트
handelClickBtn = () => {
// react에서 push 쓰는 법
// react에서 state 내부의 값을 직접적으로 수정하면 안된다
// push, splice, unshift, pop은 배열 자체를 직접적으로 수정하므로 적합x
// 기존 배열에 기반하여 새 배열을 만들어내는 concat, slice, map, filter 함수 사용
// let inputArr = this.state.inputCommentUp;
// let inputWord = this.state.inputComment;
// inputArr.push(inputWord)
// this.setState({inputCommentUp: inputArr})
this.setState({
inputCommentUp: this.state.inputCommentUp.concat(this.state.inputComment)
})
}
맨 처음 push를 썼었는데 push는 함수가 아니라는 type error가 떴었다
찾아보니 react에서 state 내부의 값을 직접적으로 수정하면 안돼,
배열 자체를 직접적으로 수정하는 push 함수는 사용할 수 없고 간접적으로 변수를 선언해서 하는 것은 가능했다
concat
을 쓰면 에러가나지 않는데,
concat()
메서드는 인자로 주어진 배열이나 값들을 기존 배열에 합쳐서 새 배열을 반환한다
참고 : MDN concat
concat을 사용했더니 오류가나지 않았다
input 태그를 통해 입력받은 값을 this.setState
로 inputCommentUp
에 값을 업데이트 한다
의문점
솔직히 왜 빈배열을 선언해야 되는지 정확히는 모르겠다
태그자체를 배열의 요소로 본걸까?
댓글을 추가할때 map함수를 써서 반환했는데 그 함수를 사용하려고 빈 배열에 값을 추가하는 것 같기도하다
DOM에서는 그냥 태그를 생성하면 됐었던건데 편하면서도 원리를 완전히 이해하지는 못하겠다
input
태그에 onChange
이벤트를 넣어준다<input
className="a-c-i-addtext"
type="text"
placeholder="댓글 달기..."
onChange={this.handleChangeInput}
/>
onClick
이벤트를 넣어준다<button
type="button"
className="a-c-i-button"
onClick={this.handelClickBtn}
>
게시
</button>
기존 댓글 태그 밑에 map 함수로 댓글 구조 반환
게시버튼을 클릭하면 onClick
이벤트가 발생하여 댓글 form이 추가 된다
{this.state.inputCommentUp.map((inputComment,idx) => {
return (
<div className="a-t-c-form" key={idx}>
<a className="link a-t-c-userid" href="true">unknown user</a>
<span className="a-t-c-content">{inputComment}</span>
<button className="a-t-c-comment-del">삭제</button>
</div>
)
})}
map()
메서드는 배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환한다
참고 : MDN map
버튼을 클릭하기전 아직은 빈 배열인 inputCommentUp
을 불러와서 map 함수를 시행한다
parameter 는 inputComment
(input 태그 입력값), idx
키 값,
return 값으로 댓글 구조를 반환한다
react
에서 map 함수에서 key
는 필수로 들어가야 하고
key
는 배열을 렌더링을 할 때 꼭 필요한 값이라고 한다 (없어도 실행은 된다)
react
는 배열을 렌더링할 때 값을 통하여 업데이트 성능을 최적화한다
아래 예를 통해서 좀 더 자세히 살펴보면
<div>A</div> <div>B</div> <div>C</div> <div>D</div>
만약에
key
를 부여하지 않으면, 배열의index
값이 자동으로key
로 설정이되는데,
key
가 배열의 인덱스로 설정되면 아래와 같이 보인다<div key={0}>A</div> <div key={1}>B</div> <div key={2}>C</div> <div key={3}>D</div>
배열의 index가 key 값으로 사용됐다
여기서B
와C
사이에X
를 추가한다고 하면 아래와 같이 보인다<div key={0}>A</div> <div key={1}>B</div> <div key={2}>X</div> [C -> X] <div key={3}>C</div> [D -> C] <div key={4}>D</div> [새로 생성됨]
중간에 끼워넣기만하면 되는데,
배열의 index를 key로 사용하게되어 중간에 값이 들어가면 index도 바뀌어 추가된 값 밑으로 함께 변경되었다
key를 배열의 index 값으로 사용하는게 아니라, 데이터를 추가할 때마다 고정적인 고유 값을 부여해주면,
react가 변화를 감지해내고 업데이트를 하게 될 때 조금 더 효율적으로 처리할 수 있게 된다
고정적으로 값을 부여하면 아래와 같이 추가되어도 기존 key의 값은 변경되지 않는다<div key={0}>A</div> <div key={1}>B</div> <div key={4}>X</div> // 새로 생성됨 <div key={2}>C</div> // 유지됨 <div key={3}>D</div> // 유지됨
결국 새로운 DOM은 하나만 생성되고, 나머지는 그대로 유지된다
key값은 언제나 고유해야 되기 때문이다
자세한 사항은 참고한 블로그에서 좀 더 자세히 볼 수 있다 (출처 : https://velopert.com/3636)
이벤트가 발생할 때 전달되는 매개변수 e
를 꼭 지정해줘야 한다
입력되는 값의 e.key
가 Enter
와 같으면 미리 만들어준 handleClick
함수를 실행시킨다
handleKeyPressInput = (e) => {
if (e.key === 'Enter') {
this.handleClickBtn();
}
}
input 태그에 엔터키가 입려되면 댓글을 추가하기 위한 onKeyPress
이벤트를 추가해준다
댓글 입력 태그에 글자가 입력되면 onKeyPress
이벤트가 실행되므로,
handleKeyPressInput
함수가 실행되는데 엔터키가 입력되면 조건에 만족하므로 true
ture
일때 블록의 내용인 입력받은 값을 배열에 저장하는 handelClickBtn
함수가 실행된다
<input
className="a-c-i-addtext"
type="text"
placeholder="댓글 달기..."
onChange={this.handleChangeInput}
onKeyPress={this.handleKeyPressInput}
/>
아직 DOM의 이벤트랑 리액트의 이벤트거는 방식이 충돌해서 헷갈린다
그래도 초기 세팅은 DOM보다는 편한것 같다..아직 내가 못할뿐 ㅠㅠ
좀 더 열심히 다른 코드들을 봐야겠다. 많은 코드를 보면서 이해하는 것이 중요한 것 같다
왜 버튼을 클릭하면 map이 자동으로 실행되는지 아직 잘 모르겠다..
input 값을 추가한 배열을 넣어줘서 그런가? 거기에 값이 생성되서 근데 입력값이 없어도 게시버튼을 누르거나 엔터키를 입력하면 댓글이 추가되긴하는데,, 아 그건 내가 버튼을 눌러서 이벤트가 발생해서 그렇구나
많은 것들이 꼬여서 아직은 많이 헷갈린다
좀 더 많은 코드를 보면서 공부하면 나아지겠지