그런데, state 변수를 다 만들기는 너무많고 귀찮다..
객체로 만들어보자❗️
한번에 몰아서 이 객체를 변수에 저장하겠다.
activity.likeCnt
activity.writerEmail
activity.createdDate
이런형태로 가져옴.
하지만❗️ 아직 data에서 받아온거 없으니깐 null 값으로 바꿔준다.
📌 "?"
연산자
최초로 그려질때 처음에 값은 null
이니까, 보여줄게없어서 오류가 난다. 원래는 activity가 null결과가 나오면 오류가 나는데, 그래서, ?
를 사용하면 오류가 나오지않고, undefined 이 나온다.
activity가 null이 아닐때만, 보여준다.
{activity.title !== null && activity.title}
{activity?.title}
?
물음표를 안쓰면 오류가 난다. 처음값이 null 이기떄문에, 물음표를 사용함으로써.
10개 하나하나 다 쓰기는 너무 귀찮잖아. 언제 다써?
그래서 ...activity
-> activity 풀어주는 역할.
- 배열에서 사용 가능
- 객체에서 사용 가능
배열 예시
let ar = [ 10, 20, 30 ]; let ar2 = [ 0, ...ar , 90 ] ; // ar2 :
ar2[0] = 100; // ar2 : [100, 20, 30, 40, 50, 60, 70, 80, 90, 100] // ar : [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
객체 예시
let book = { title:'대모험', page: 20, author:'홍길동' } let book2 = { title:book.title, page:book.page, author:book.author };
let book2 = { ...book , price:100 , title:'홍길동전'};
title이 두개면, 마지막것으로 덮어쓴다. 그래서 대모험은 사라지고 홍길동전생김.
새로운객체를 만들어줘.!
...activity
는 그전 거 그대로 나오고,
setActivity({ ...activity ,
liked:'no',
activity_like : activity.activity_like - 1});
const onLikeClick = async ()=>{
if(activity.liked === 'yes'){
try{
await axios.delete('/api/like', {
data:{id:activity.id},
headers:{Authorization:`Bearer ${accessToken}`}
});
setActivity({ ...activity , liked:'no', activity_like : activity.activity_like - 1});
}catch(err){
console.log(err);
alert('좋아요 현재 수정 불가');
}
}else{
try{
await axios.post('/api/like',
{id:activity.id},
{headers:{Authorization:`Bearer ${accessToken}`}}
);
setActivity({...activity , liked:'yes', activity_like:activity.activity_like+1});
}catch(err){
console.log(err);
alert('좋아요 오류');
}
}
}
아이디가 1번인거를 먼저 조회를 한다.
try{
let sql = `
select activity_view
from tbl_activities
where id = ?;
`;
let [ views ] = await pool.query(sql, [id]); //현재 조회수를 가져와서,
sql =`
update tbl_activities
set activity_view = ?
where id = ?;
`;
await pool.query(sql, [ views[0].activity_view + 1 , id]) //현재조회수에서 더하기 1 한값을 구해줘.
//views[0].activity_view 👉 현재조회수를 뜻함
새로고침할때마다 올라가게 안하고,
ip 주소를 받아와서 아이피주소가 본적없는것만 확인해서 그걸고 조회수가 올라가게 할수있다.
owner 이면 보고 아니면 안보이고
{ activity?.owner && <div style={{ alignSelf: 'flex-end', display: 'flex', columnGap: '10px' }}> <WriteBtn>수정하기</WriteBtn> <WriteBtn style={{ backgroundColor: 'red' }}>삭제하기 </WriteBtn> </div> }
activityDetailSection.js
const ActivityDetailSection = (props) => {
const [activity, setActivity] = useState(null); //게시글 정보
const { accessToken } = useContext(UserContext);
useEffect(() => {
let tmp = async () => {
if (accessToken === null) return;
try {
let res = await axios.get(`/api/activities/${props.activityId}`, {
headers: { Authorization: `Bearer ${accessToken}` }
});
setActivity(res.data); //조회수증가
// setIsLiked(res.data.liked === 'yes');
} catch (err) {
console.log(err);
alert('오류가 발생했어요.')
}
}
tmp();
}, [props.activityId, accessToken]);
const onLikeClick = async () => {
if (activity.liked === 'yes') {
try {
await axios.delete('/api/like', {
data: { id: activity.id },
headers: { Authorization: `Bearer ${accessToken}` }
});
setActivity({ ...activity, liked: 'no', activity_like: activity.activity_like - 1 });
} catch (err) {
console.log(err);
alert('좋아요 현재 수정 불가');
}
} else {
try {
await axios.post('/api/like',
{ id: activity.id },
{ headers: { Authorization: `Bearer ${accessToken}` } }
);
setActivity({ ...activity, liked: 'yes', activity_like: activity.activity_like + 1 });
} catch (err) {
console.log(err);
alert('좋아요 오류');
}
}
}
return (
<section>
<BoardDetailWrap>
<BoardTitle>
{activity?.title}
<div style={{ display: 'flex', alignItems: 'baseline' }}>
<span>좋아요:{activity?.activity_like} </span>
<span onClick={onLikeClick}>
{activity?.liked === 'yes' ? <FavoriteIcon style={{ color: 'red' }} /> : <FavoriteBorderIcon />}
</span>
</div>
</BoardTitle>
<BoardInfoWrap>
<p>작성자</p>
<p>{activity?.writer_email}</p>
<p>조회수</p>
<p>{activity?.activity_view}</p>
</BoardInfoWrap>
<BoardInfoWrap>
<p>작성일자</p>
<p>{activity?.created_date}</p>
<p>수정일자</p>
<p>{activity?.updated_date}</p>
</BoardInfoWrap>
<BoardContent>
{activity?.img_url.map((img) => <div>
<img style={{ width: '100%' }} src={img} alt="이미지" />
</div>)}
{activity?.content}
</BoardContent>
{
activity?.owner &&
<div
style={{
alignSelf: 'flex-end',
display: 'flex',
columnGap: '10px'
}}>
<WriteBtn>수정하기</WriteBtn>
<WriteBtn
style={{ backgroundColor: 'red' }}>삭제하기
</WriteBtn>
</div>}
</BoardDetailWrap>
</section>
)
}
export default ActivityDetailSection;