카테고리 없음
React) Instagram 간단하게 한 클론코딩 (댓글추가 구현)
헬리이
2023. 1. 28. 02:37
728x90
인스타 그램 클론코딩 중
내가 아주 애먹었던 😂 댓글구현 과정..
드디어.. 이해가좀 되어 이렇게 정리하면서 업로드 해본다 👀👊
내가 한 방법은
1. 댓글을<input>에 입력하면 comment 라는 state(초기값=[])에 받아와서 commentList라는 state에 추가하고,
2. 그 배열 형태롤 추가한 commentList에 map함수를 돌려서 배열안에 있는 데이터를 하나씩 가져온 후
3. 배열에서 가지고온 데이터를 <Comment>라는 컴포넌트에 props로 넘겨주었고,
4. 댓글이 꾸려지도록 가져온 {props.data.commentItem} 로 구현해 보았다.
말로 풀어봤지만.. 뭐라는거지..? 라도 할 수 있으니 코드도 한번 넣어보았다...ㅠ
//Main.js
function MainFeed() {
const [commentList, setCommentList] = useState([
{
// id: 'MingGu'<Comment> 컴포넌트에 지정을 해 주어 주석처리 하였다.
commentItem: '나를 두고가다니..👊!! 가만두지 않겠다옹!!👿',
},
]);
//comment가 저장되는 리스트 이며, id : 단순히 고유값을 보여주기위해 지정했다.,comment: 댓글
const [comment, setComment] = useState('');
//<input/>댓글
const saveComment = () => {
setCommentList([...commentList, { commentItem: comment }]);
setComment(''); //<input>에 내용을 적은 후 적었던 내용 초기화하기 위한 것
};
//comment가 저장되는 리스트에 리스트 객체를 추가하는것 . comment는받아오는 값이라, setComment로 comment로저장
commentList : input에 입력된 댓글이 업로드 될 공간으로 [ ] 배열형태를 띄고 있으며 , 초기값에는 미리 작성될 코멘트(commentItem)를 넣어주었다.
comment : input에 들어갈 댓글이며, (' ' )빈 문자열을 초기값으로 가지고 있다.
saveComment = () => {}
: 댓글이 저장되는 commentList에 댓글을 추가하는 함수로, ...commentList는 위에 미리 작성된 초기값을 불러오는 역할을 한다.
미리 작성된 초기값을 불러와야하므로 배열의 순서가 ...commentList가 먼저왔으며, 그 후 {commentItem : comment } 가 오게되었다.

//Main.js 댓글 들어가는 곳
<div className="commentSection">
<ul className="comments">
{commentList.map((obj, idx) => (
<Comment data={obj} key={idx} />
//obj (obj=객체=패키지)를 불러왔다.
//Comment라는 컴포넌트에 {obj}를 data라는 이름으로 넘겨주었다.
//이때, map함수를 사용하였고, map 함수 적용시 엘리먼트의 고유성을 부가해 주기위해 key를 꼭 넣어줘야한다.
))}
</ul>
</div>
<span className="commentTime">16분 전</span>
</div>
여기가 그 문제의 구간이었다....
여기서 <Comment>인 자식 컴포넌트로 넘겨준 data이름을 가진 {obj} 함수는
일단 댓글을<input>에 입력하면 comment 라는 state(초기값=(' '))에 받아와서
commentList라는 state에(배열[ ]) 추가하고,
그 배열 형태롤 추가한 commentList에 map함수를 돌려서 배열안에 있는 데이터를 하나씩 가져온 후
배열에서 가지고온 데이터를 <Comment>라는 컴포넌트에 data라는 이름으로 props로 넘겨준 것이다.
Comment 컴포넌트에 부모 컴포넌트인 Main.js에서 props로 가져온 것을 보면
//<Comment.js> Comment 라는이름을 가진 컴포넌트
function Comment(props) { //부모 컴포넌트에서 props해서 가져왔다.
useEffect(() => {
//useEffect : 화면이 렌더링 될때 실행하는것
console.log(props);
}, []);
//화면이 매번 렌더링 되는게 아니고 데이터 값이 바뀔때 하는거라
//[] dependency 라고 하는것에 상태가 바뀌었는지 감지해야하는 데이터를 넣어준다.
return (
<div>
<li className="commentBox">
<span className="boldPoint">MingGu</span> //여기서 아이디를 이미 적었기 때문에 위에서 주석처리함
<span className="commentContext">{props.data.commentItem}</span>
//props를 이용해 부모 컴포넌트의 data라는 이름을 가진 함수와 commentItem에 적은 내용을 불러왔다.
<img
className="commentHeart"
src="https://cdn-icons-png.flaticon.com/512/1216/1216575.png"
alt="코멘트하트"
/>
</li>
</div>
);
}
그 후
게시 버튼을 누르거나, Enter를 누르면 <input>에 기입된 댓글이 업로드 되도록 코드도 넣었다.
//Main.js return 위에서 선언해준 saveComment 함수
const saveComment = () => {
setCommentList([...commentList, { commentItem: comment }]);
setComment(''); //댓글을 작성 후 게시 후 <input>에 이미 작성된 댓글을 다시 초기화 시켜주는 코드
};
//Main.js
<div className="putComment">
<input
onChange={e => {
setComment(e.target.value);
}} //input에 입력을 하는순간 comment를 변경해주는 이벤트 발생
className="inputComment"
type="text"
value={comment} //입력되는 comment 값을 가져야 하니
placeholder="댓글 달기..."
onKeyPress={e => {
if (e.key === 'Enter') {
saveComment();
} //Enter는 키보드로 입력되는 comment가 작성된 후 누르게 될 것이므로 <input>에서 이벤트가 발생하게 하였다.
}}
/>
<button
className="submitComment"
type="submit"
onClick={saveComment}
> //'게시'버튼을 눌렀을 때 또한 댓글이 업로드되게 해야하므로 onClick 이벤트를 주었다.
게시
</button>
</div>

이 댓글 구현을 위해 엄청 많이 힘들었는데,
useState와 props의 개념이 완벽하게 잡히지 않은 상태에서 자꾸 해보려 하니깐 안되었던것 같았다. 👀
지금도 완벽은 아니지만, 그래도 개념정리를 하고 난 후 다시 시도하니, 전보다 이해를 하면서 코드를 칠 수 있었다.😔
어제보다 조금 더 나아진 실력이 되어 뿌듯하긴 하다만..아직 멀었다..ㅠ
728x90