소스 :
https://github.com/braverokmc79/macaronics-react-udemy-ex24/tree/complex
App.jsx
{
path: "/events/:id",
element: <EventDetails />,
children: [
{
path: "/events/:id/edit",
element: <EditEvent />,
loader:editEventLoader,
action:editEventAction
},
],
},
EditEvent.jsx
import { Link, Outlet, useNavigate, useParams } from 'react-router-dom';
import Header from '../Header.jsx';
import { useMutation, useQuery } from '@tanstack/react-query';
import { deleteEvent, fetchEvent, queryClient } from '../../util/http.js';
import LoadingIndicator from '../UI/LoadingIndicator.jsx';
import ErrorBlock from '../UI/ErrorBlock.jsx';
import { useState } from 'react';
import Modal from '../UI/Modal.jsx';
export default function EventDetails() {
const [isDeleting, setIsDeleting]=useState(false);
const navigate=useNavigate();
const {id} =useParams();
const {data, isPending, isError, error }=useQuery({
queryKey:['events', id],
queryFn:({signal})=>fetchEvent({id, signal}),
//캐시처리된지 10초 미만인 경우 내부적으로 다시 가져오지 않고 캐시된 데이터를 사용된다.
staleTime:10000
})
const {
mutate, isPending:isPendingDeleting, isError: isErrorDeleting, error: deleteError} = useMutation({
mutationFn: deleteEvent,
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: ['events'] ,
refetchType: 'none'
});
navigate('/events');
},
});
function handleStopDelete(){
setIsDeleting(false);
}
function handleStartDelete(){
setIsDeleting(true);
}
function handleDeleteEvent(formData) {
mutate({
id:id
});
}
let content="";
if(isPending){
content=(
<div id="event-details-content" className='center'>
<p>이벤트 데이터 가져오는 중...</p>
<LoadingIndicator />
</div>
)
}
if(isError){
content=
<div id="event-details-content" className='center'>
<ErrorBlock title="에러가 발생 했습니다." message={error.info?.message || '이벤트를 가져오지 못했습니다.'} />
</div>
}
if(data&& data.image){
const formattedDate=new Date(data.date).toLocaleDateString("ko-KR", {
day:'numeric',
month:'short',
year:'numeric',
hour:'2-digit',
minute:'2-digit',
})
content=<>
<header>
<h1>{data.title}</h1>
<nav>
<button onClick={handleStartDelete}>삭제</button>
<Link to="edit">편집</Link>
</nav>
</header>
<div id="event-details-content">
<img src={`http://localhost:3000/${data.image}`} alt={data.title} />
<div id="event-details-info">
<div>
<p id="event-details-location">{ data.location}</p>
<time dateTime={`Todo-DateT$Todo-Time`}>{formattedDate} @ {data.time}</time>
</div>
<p id="event-details-description">{data.description}</p>
</div>
</div>
</>
}
return (
<>
{isDeleting &&(
<Modal onClose={handleStopDelete}>
<h2>확인</h2>
<p>정말로 이 이벤트를 삭제하시겠습니까? 이 작업은 취소할 수 없습니다.</p>
<div className='form-actions'>
{isPendingDeleting &&<p>삭제 처리중...</p>}
{!isPendingDeleting &&
<>
<button onClick={handleStopDelete} className='button-text'>취소</button>
<button onClick={handleDeleteEvent} className='button'>삭제</button>
</>
}
</div>
{isErrorDeleting &&<ErrorBlock title="이벤트 삭제에 실패 하였습니다."
message={error.info?.message || '이벤트 삭제에 실패 하였습니다.'} />}
</Modal>
)}
<Outlet />
<Header>
<Link to="/events" className="nav-item">
모든 이벤트 보기
</Link>
</Header>
<article id="event-details" className='text-center'>
{content}
</article>
</>
);
}














댓글 ( 0)
댓글 남기기