import React, { Component } from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faHeart as heartInactive } from '@fortawesome/free-regular-svg-icons';
import { faHeart as heartActive } from '@fortawesome/free-solid-svg-icons';
import { faTrashAlt } from '@fortawesome/free-regular-svg-icons';
import LikeButton from '../../../components/LikeButton/LikeButton';
import './Review.scss';
class Review extends Component {
constructor() {
super();
this.maxId = 3;
this.state = {
userValue: '',
textValue: '',
comments: [
{
id: 1,
userName: 'jeju',
comment: '비자림이 그저 forest?',
isLiked: false,
},
{
id: 2,
userName: 'dabin',
comment: '흑임자 쑥 프라푸치노 드세요',
isLiked: false,
},
{
id: 3,
userName: 'darling',
comment: '멍멍멍멍 왈왈왈왈',
isLiked: false,
},
};
}
//리뷰 입력 창 변화 감지시 value를 state에 저장, 비구조화 할당 적용
getValue = e => {
const { value, name } = e.target;
this.setState({
[name]: value,
});
};
addReview = e => {
const { userValue, textValue } = this.state;
//참조형에서의 얕은 복사: 서로 같은 주솟값을 바라보기 때문에 원본도 수정됨
let newComments = this.state.comments;
this.maxId = this.maxId + 1;
//이름+내용 존재할 때만 add review
if (userValue !== '' && textValue !== '') {
newComments = newComments.concat({
id: this.maxId,
userName: this.state.userValue,
comment: this.state.textValue,
isLiked: false,
});
this.setState({
comments: newComments,
userValue: '',
textValue: '',
});
} else {
alert('이름과 댓글 모두 입력해주세요 ♡◟(●•ᴗ•●)◞♡');
}
};
//input창에서 enter키를 눌렀을 때에도 addReview가 동작
addReviewByEnter = e => {
if (e.key === 'Enter') {
this.addReview();
e.target.value = '';
}
};
removeReview = id => {
//친절하게 삭제 여부를 다시 확인받기!
if (window.confirm('진짜 삭제하고 싶어요?( •_ •̥ ˳ ˳ )')) {
const { comments } = this.state;
//id는 인자로 전달받은 댓글추가 당시 userValue
const nextComments = comments.filter(comment => comment.id !== id);
this.setState({
comments: nextComments,
});
}
};
//좋아요 버튼은 isLiked를 데이터로 저장할 수 있어야 한다.
//댓글 좋아요 버튼 클릭시 id가 일치하는 댓글을 찾아 그 댓글의 isLiked만 변경한다.
likeButtonClicked = id => {
const { comments } = this.state;
const likedComments = comments.map(comment => {
if (comment.id === id) {
comment.isLiked = !comment.isLiked;
}
return comment;
});
this.setState({ comments: likedComments });
};
render() {
return (
<>
<div className="Review">
<h3 className="reviewTitle">리뷰</h3>
<div className="comments">
<ul className="commentsBox">
{this.state.comments.map((review, id) => {
return (
<li className="addedReview" key={id}>
<p className="addedName">{review.userName}</p>
<p className="addedComment">{review.comment}</p>
<i
onClick={() => this.likeButtonClicked(review.id)}
className="LikeButton commentLikeButton"
>
<FontAwesomeIcon
icon={review.isLiked ? heartActive : heartInactive}
className={review.isLiked ? 'fillHeart' : ''}
/>
</i>
//인자를 전달하기 위해 화살표 함수 사용
<i onClick={() => this.removeReview(review.id)}>
<FontAwesomeIcon icon={faTrashAlt} key={review.id} />
</i>
</li>
);
})}
</ul>
</div>
<div className="pushBox">
<input
className="userNameInput"
name="userValue"
type="text"
value={this.state.userValue}
placeholder="name"
required
onChange={this.getValue}
onKeyPress={this.addReviewByEnter}
/>
<input
className="reviewText"
name="textValue"
type="text"
value={this.state.textValue}
placeholder="리뷰를 입력해주세요"
required
onChange={this.getValue}
onKeyPress={this.addReviewByEnter}
/>
<button className="push" onClick={this.addReview}>
POST
</button>
</div>
</div>
</>
);
}
}
export default Review;
디테일 페이지는 하나의 컴포넌트 안에서 like button을 처리했지만, list page에서는 부모와 자식 컴포넌트를 넘나들며 구현해야 했다.
//List.js
//자식 컴포넌트에 전달
{coldbrew.map(data => {
return (
<CoffeeCard
key={data.id}
id={data.id}
title={data.title}
img={data.img}
isLiked={data.isLiked}
likeButtonClicked={() =>
this.likeButtonClicked(coldbrew, data.id)
}
/>
);
})}
//CoffeeCard.js
//props로 전달받은 데이터를 적용
<div className="CoffeeCard">
<div className="coffeeImgWithIcon">
<img
className="coffeeImg"
alt={this.props.title}
src={this.props.img}
onClick={this.moveToDetailPage}
/>
<label className="listLikeButton">
<i onClick={this.props.likeButtonClicked} className="LikeButton">
<FontAwesomeIcon
icon={this.props.isLiked ? heartActive : heartInactive}
className={this.props.isLiked ? 'fillHeart' : ''}
/>
</i>
</label>
</div>
<p className="listPageCoffeeName">{this.props.title}</p>
</div>