글 작성자: 개발자 올라프

📝 개요

 

  • JavaScript로 구현한 로그인, 댓글 기능을 React로 바꾸고자 한다.
  • 댓글 기능을 구현하면서 React의 props, state 개념을 이해한다.

 


 

댓글을 구현하기 위해 사용한 state

let [userName] = useState('hacker');
let [comment, setComment] = useState('');
let [feedComments, setFeedComments] = useState([]);
let [isValid, setIsValid] = useState(false);
  • userName 같은 경우는 사용자 정보를 받아오지 않고 'hacker'라는 내용을 담아놓고 사용하고 있다.
  • comment는 사용자가 입력하고 있는 댓글이다. <input> 태그에서 onChange를 이용하여 comment 값을 계속 담을 것이다.
  • feedComments는 댓글 리스트를 담으려고 만들었다.
  • isValid는 댓글 게시 가능 여부, 유효성 검사를 위해 만들었다.

 

유효성 검사를 통과하고 '게시' 클릭 시 발생하는 함수 post 구현

let post = e => {
    const copyFeedComments = [...feedComments];
    copyFeedComments.push(comment);
    setFeedComments(copyFeedComments);
    setComment('');
};
  • 전개 연산자를 통해서 feedComments에 담겨있던 댓글을 받아온다.
  • 기존 댓글 배열들이 담겨있는 copyFeedComments에 사용자가 입력한 comment를 push 한다.
  • 사용자가 입력한 comment가 담겨있을 feedComment 값을 setFeedComment로 변경한다.
  • 사용자가 입력하는 댓글창을 '' 빈 문자열로 초기화한다.

 

사용자가 댓글을 입력하는 창 <input>

<input
    type="text"
    className="inputComment"
    placeholder="댓글 달기..."
    onChange={e => {
    	setComment(e.target.value);
    }}
    onKeyUp={e => {
    	e.target.value.length > 0
    		? setIsValid(true)
    		: setIsValid(false);
    }}
    value={comment}
/>
  • 댓글 창의 상태가 변할 때마다 setComment를 통해 comment의 값을 바꿔준다.
  • 사용자가 키를 눌렀다가 떼었을 때 길이가 0을 넘는 값인지 setIsValid에 유효성 검사 결과 값을 담는다.

 

사용자가 댓글을 입력하고 누르는 게시 버튼

<button
    type="button"
    className={
    	comment.length > 0
    	? 'submitCommentActive'
    	: 'submitCommentInactive'
    }
    onClick={post}
    disabled={isValid ? false : true}
>
    게시
</button>
  • 클래스명을 현재 comment 창의 글자 길이에 따라서 다르게 주었다. 이를 통해 상황에 맞는 게시 버튼 색 CSS 디자인을 줄 수 있었다.
  • 클릭하면 위에서 선언한 post 함수를 실행하여 feedComments에 담겨서 re-rendering 된 댓글창을 확인할 수 있다.
  • 사용자가 아무것도 입력하지 않았을 경우 게시를 할 수 없도록 하였다.

 

사용자들의 댓글을 담은 feedComments

{feedComments.map((commentArr, i) => {
    return (
        <CommentList
            userName={userName}
            userComment={commentArr}
            key={i}
        />
    );
})}
  • feedComments에 담겨있을 댓글 값을 <CommentList> 컴포넌트에 담아서 가져온다.
  • <CommentList> 컴포넌트는 반복적으로 추가되는 사용자 댓글 하나하나를 담고 있는 박스이다.
  • userName에는 위에서 'hacker'를 담은 값을, userComment에는 feedComments에 담겨 있는 댓글 배열을 담는다.

 

 

반복적으로 들어갈 댓글 요소들을 컴포넌트화

const CommentList = props => {
    return (
        <div className="userCommentBox">
            <p className="userName">{props.userName}</p>
            <div className="userComment">{props.userComment}</div>
            <p className="userHeart">
           		<FaHeart />
            </p>
        </div>
    );
};
  • feedComments.map을 통해 계속 <CommentList> 컴포넌트가 댓글 배열 수만큼 불려서 위 태그 모양대로 생성된다.
  • props를 통해서 유저명 hacker를 계속 넣고, props.userComment에는 부모의 댓글 배열 값을 받아서 feedComments에게 불려진다.