setIsPending(res.data.pendingGroups.includes(group => group._id === groupId) ? true : false);
신청중인 그룹에 해당 페이지의 그룹 id가 있는지 확인 → 있으면 신청중, 없으면 신청하기
이렇게 하려고 했는데 includes 메서드가 적절하지 않다는걸 알게됨
setIsPending(res.data.pendingGroups.some(group => group._id === groupId) ? true : false);
상세 그룹 페이지 그룹 리더 정보 id로 가져와서 게시글 작성자로 설정하는거 해야됨
그리고 그룹 id 로 조회해서 그룹 정보 업데이트하는거 해야됨
{Object.keys(top3).length > 0 && Object.keys(other).length > 0 ? (
<>
<UserRank userTop3={top3.userTop3} userOther={other.userOther} />
<GroupRank groupTop3={top3.groupTop3} groupOther={other.groupOther} />
</>
) : (
'하이'
)}
state 값이 제대로 업데이트 될 때 컴포넌트를 랜더링 하고싶었는데 계속 undefined 에러 뜸
이렇게 조건부 랜더링을 통해 해결
—> 이거보다 setState 콜백을 통해서 해결하는게 나을듯..
setState 콜백은 언제쓸까?
: react에서 setState의 Callback 함수를 사용하는 경우는 state를 변경 후 변경된 state를 사용하는 경우입니다.
이렇게 하니까 바로 해결된다 ㅜㅜㅜㅜ
import React, { useEffect, useState } from 'react';
import { API } from '../../utils/axios';
import { chatSocket } from '../../utils/socketServer';
import { useSelector } from 'react-redux';
import { useParams, useNavigate, useLocation } from 'react-router-dom';
import { IoMdArrowRoundBack } from 'react-icons/io';
import Button from '../../components/common/Button';
import { Badge } from 'flowbite-react';
export default function DetailGroupPage() {
const { groupId } = useParams();
// const location = useLocation();
// console.log('@@@#$@#$#@$#@$@#$ location 새로고침>>>>', location);
// const { groupInfo } = location.state;
const [groupInfo, setGroupInfo] = useState({});
const [isPending, setIsPending] = useState(null);
const { id: userId, nickName: userName } = useSelector(state => state.user?.userInfo);
const [leaderName, setLeaderName] = useState('');
const [profileImgPath, setProfileImgPath] = useState('');
// const { subject, imagePath, category, description, time, leader, maxMember } = groupInfo;
// console.log('룸아이디 오는거 확인>>>', roomId);
// console.log('그룹정보 오는거 확인>>>', groupInfo);
// console.log('잘되나>>', subject, imagePath, category, description, time, leader, maxMember);
const navigate = useNavigate();
// 채팅창 이동
const handleChat = () => {
chatSocket.emit('login', userName, res => {
if (res && res.isOk) {
console.log('successfully login', res);
navigate(`/group/chat/${groupId}`);
} else {
console.log('fail to login', res);
alert('로그인해주세요!');
}
});
};
// 뒤로가기
const handleGoBack = () => {
navigate(-1);
};
// 그룹 삭제
const deleteGroup = async () => {
try {
const res = await API.delete(`group/studyGroup/${groupId}/members`);
// console.log(res.data.message);
alert(`${res.data.message}`);
navigate('/');
} catch (error) {
console.error('그룹 삭제에 실패하셨습니다. ->', error);
}
};
//그룹 탈퇴
const leaveGroup = async () => {
try {
const res = await API.delete(`group/studyGroup/${groupId}`);
// console.log(res.data.msg);
alert(`${res.data.msg}`);
navigate('/');
} catch (error) {
console.error('그룹 탈퇴에 실패하셨습니다. ->', error);
}
};
useEffect(() => {
const getGroupInfo = async () => {
try {
const res = await API.get(`/group/find/${groupId}`);
if (res.data.isSuccess) {
setGroupInfo(prevGroupInfo => {
const newGroupInfo = res.data.GroupInfo;
if (Object.keys(newGroupInfo).length > 0) {
(async () => {
const leaderRes = await API.get(`/user/${newGroupInfo.group_leader}`);
if (leaderRes.data.isSuccess) {
const leaderInfo = leaderRes.data.userInfo;
setLeaderName(leaderInfo.nick_name);
setProfileImgPath(leaderInfo.user_profile_image_path);
}
})();
}
return newGroupInfo;
});
}
} catch (err) {
console.error(err);
}
};
getGroupInfo();
}, [groupId]);
useEffect(() => {
const getPendingGroups = async () => {
try {
const res = await API.get('/group/pendingGroups');
setIsPending(res.data.pendingGroups.some(group => group._id === groupId) ? true : false);
} catch (error) {
console.error('Error fetching pending groups:', error);
}
};
getPendingGroups();
}, [groupId, isPending]);
const handleGroupRequest = async groupId => {
try {
const res = await API.post(`/group/studyGroup/${groupId}/join`);
if (!res.data.isFull) {
const data = res.data.message;
setIsPending(true);
alert(data);
} else {
alert(`${res.data.message}`);
}
} catch (err) {
console.error(err.message);
alert('요청 처리 중 오류가 발생했습니다.');
}
};
const handleCancelRequest = async () => {
try {
const res = await API.delete(`/group/studyGroup/${groupId}/joinRequests`);
if (res.data.isSuccess) {
setIsPending(false);
alert(`${res.data.message}`);
}
} catch (err) {
console.error(err);
}
};
const {
_id,
daily_goal_time,
group_category,
group_description,
group_image_path,
group_leader,
group_maximum_member,
group_name,
members,
} = groupInfo;
return (
<>
{Object.keys(groupInfo).length === 0 && <div className="loading">로딩 중...</div>}
{Object.keys(groupInfo).length > 0 && leaderName && profileImgPath && (
<div className="studyContentWrap flex flex-col break-all">
<section className="studyContent_postHeader mb-5">
<div className="btnWrap flex justify-between items-center mb-5">
<Button handleClick={handleGoBack} customStyle={'!bg-transparent !text-primary !text-3xl'}>
{<IoMdArrowRoundBack />}
</Button>
{!members.includes(userId) ? (
isPending ? (
<Button handleClick={handleCancelRequest} customStyle={'self-end'}>
신청취소
</Button>
) : (
<Button handleClick={() => handleGroupRequest(groupId)} customStyle={'self-end'}>
신청하기
</Button>
)
) : (
<Button handleClick={handleChat} customStyle={'self-end'}>
채팅창 이동하기
</Button>
)}
</div>
<div className="studyContent_title mb-3">
<h1>{_id}에 대한 상세 페이지 레고</h1>
{/* 그룹 제목 */}
<h1 className="font-bold text-5xl">{group_name}</h1>
</div>
<div className="studyContent_user flex items-center mb-3">
{/* 그룹장 */}
<img
className="rounded-full w-10 h-10 me-3"
src={import.meta.env.VITE_APP_BACK_URL + profileImgPath}
alt="유저 프로필 이미지"
/>
<span className="font-bold text-lg">{leaderName}</span>
</div>
<section className="studyInfoWrap md:w-1/2 w-full">
<ul className="grid md:grid-cols-2 grid-cols-3 gap-2">
<li className="p-2 flex md:flex-row flex-col items-center gap-2">
<Badge color="indigo" size="lg" className="font-bold">
카테고리
</Badge>
<span className="font-semibold">{group_category}</span>
</li>
<li className="p-2 flex md:flex-row flex-col items-center gap-2">
<Badge color="indigo" size="lg" className="font-bold">
목표시간
</Badge>
<span className="font-semibold">{daily_goal_time}</span>
</li>
<li className="p-2 flex md:flex-row flex-col items-center gap-2">
<Badge color="indigo" size="lg" className="font-bold">
인원
</Badge>
<span className="font-semibold">
{members.length} / {group_maximum_member}
</span>
</li>
</ul>
</section>
</section>
<div className="studyContent_postContentWrap mb-5">
<h2 className="text-xl font-semibold">그룹 소개</h2>
<div className="studyContent_postContent w-full p-5 shadow-md min-h-[200px]">{group_description}</div>
</div>
<div className="studyContent_btnWrap self-center">
{members.includes(userId) &&
(group_leader === userId ? (
<Button handleClick={deleteGroup} customStyle={'!bg-danger'}>
그룹삭제
</Button>
) : (
<Button handleClick={leaveGroup} customStyle={'!bg-danger'}>
그룹탈퇴
</Button>
))}
</div>
</div>
)}
</>
);
}