리액트쿼리, 리액트 라우터 함께 사용하여 데이터 가져오기
import { useLoaderData } from 'react-router-dom';
function HomePage () {
const navigate = useNavigation();
const params = useParams();
//const data = useLoaderData();
// ⭐️ 위 loader() 함수에서 반환된 값을 사용하지 않고 useQuery를 계속 사용한다.
// fetchQuery를 사용하면 react-query가 해당 요청을 보내고 응답 데이터를 캐시에 저장하게 되므로, useQuery에서는 캐시된 데이터를 사용하게 된다.
// 다른 화면으로 나갔다가 다시 들어오게될 경우 내부적으로 가져오기를 트리거하여 업데이트된 데이터를 볼 수 있다.
const { data, isError, error } = useQuery({
queryKey:['events', params.id],
queryFn: ({signal}) => fetchEvent({ signal, id: params.id }),
staleTime: 10000 // ⭐️ loader함수와 중복요청 방지
})
return <EventList events={data} />
}
export default HomePage;
export function loader({params}) {
return queryClient.fetchQuery({ // ⭐️ = useQuery
queryKey:['events', params.id],
queryFn: ({signal}) => fetchEvent({ signal, id: params.id }),
});
}
리액트쿼리, 리액트 라우터 함께 사용하여 데이터 전송
import { useLoaderData } from 'react-router-dom';
function HomePage () {
const navigate = useNavigation();
const { state } = useNavigation();
const params = useParams();
const submit = useSubmit();
//const data = useLoaderData();
// ⭐️ 위 loader() 함수에서 반환된 값을 사용하지 않고 useQuery를 계속 사용한다.
// fetchQuery를 사용하면 react-query가 해당 요청을 보내고 응답 데이터를 캐시에 저장하게 되므로, useQuery에서는 캐시된 데이터를 사용하게 된다.
// 다른 화면으로 나갔다가 다시 들어오게될 경우 내부적으로 가져오기를 트리거하여 업데이트된 데이터를 볼 수 있다.
const { data, isError, error } = useQuery({
queryKey:['events', params.id],
queryFn: ({signal}) => fetchEvent({ signal, id: params.id }),
})
// const { mutate, isPending } = useMutation({
// 액션에서 모든 쿼리를 무효화함에 따라 낙관적 업데이트가 불간으
// mutationFn: updateEvent,
// onMutate:
// onError:
// onSettled:
// })
function handleSubmit(formData) {
submit(formData, { method: 'PUT' }); // ⭐️ action 함수 트리거
}
let content
if (data) {
content = (
<EventForm inputData={data} onSubmit={handleSubmit}>
{
state === 'submitting' ? <p>sending data...</p>
: <>
<Link to ="../">Cancel</Link>
<button type="submit">Update</button>
</>
}
</EventForm>
)
}
return <Modal onClose={handleClose}>{content}</Modal>
}
export default HomePage;
export function loader({params}) {
return queryClient.fetchQuery({ // ⭐️ = useQuery
queryKey:['events', params.id],
queryFn: ({signal}) => fetchEvent({ signal, id: params.id }),
});
}
export async function action({request, params}) {
const formData = await request.formData();
const updatedData = Object.formEntries(formData); // js의 object로 변환
await updateEvent({id: parmas.id, event: updatedData})
await queryClient.invalidateQueries(['events']) // ⭐️ 모든 쿼리를 무효화함으로써 업데이트된 데이터를 다시 가져옴, 낙관적 업데이트 실행 안함
return redirect('../');
}
- api.js
export async function updateEvent({ id, event }) { const response = await fetch(`http://~~/${id}`, { method: 'PUT', body: JSON.stringify({ event }), headers: { 'Content-Type': 'application/json', } }) };