소스 :
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)
댓글 남기기