type.d.ts와 같이 declare의 약자인 d를 확장자명에 붙이면 모듈의 export, import작없업이 전역적으로 사용가능하다
위와같이 export대신 declare를 선언해주면 어디서든 저 지정해준 타입을 사용할 수 있다.
supabase
useQuery
- 데이터를 get 하기 위한 api이다. (post, update는 useMutation을 사용한다.)
- 첫번째 파라미터로 unique Key(===query keys)가 들어가고, 두번째 파라미터로 비동기 함수(api호출 함수)가 들어간다.
(당연한 말이지만 두번째 파라미터는 promise가 들어가야한다.) - 첫번째 파라미터로 설정한 unique Key는 다른 컴포넌트에서도 해당 키를 사용하면 호출 가능하다. unique Key는 string과 배열을 받습니다. 배열로 넘기면 0번 값은 string값으로 다른 컴포넌트에서 부를 값이 들어가고 두번째 값을 넣으면 query 함수 내부에 파라미터로 해당 값이 전달됩니다.
- return 값은 api의 성공, 실패여부, api return 값을 포함한 객체입니다.
- useQuery는 비동기로 작동합니다. 즉, 한 컴포넌트에 여러개의 useQuery가 있다면 하나가 끝나고 다음 useQuery가 실행되는 것이 아닌 두개의 useQuery가 동시에 실행됩니다. 여러개의 비동기 query가 있다면 useQuery보다는 밑에 설명해 드릴 useQueries를 권유드립니다.
- enabled를 사용하면 useQuery를 동기적으로 사용 가능합니다. 아래 예시로 추가 설명하겠습니다.
DB통신과 관련한 로직을 한곳에 모아놓는다.
src/api/todos.js or src/axios/todos.js
import axios from "axios";
const getTodos = async () => {
const response = await axios.get("http://localhost:3000/todos");
return response;
};
export { getTodos };
유지보수를 위해 DB통신관련 로직은 한 곳에 모아놓는 것이 좋다.
useMutation
- useQuery 와 다르게 mutation은 데이터를 생성 / 업데이트 / 삭제 할 때 사용 된다.
- 내가 리액트 쿼리를 좋아하는 이유 중 큰 비중을 차지하는 queryClient 의 invalidateQueries 메소드 및 setQueryData 메소드랑 같이 사용하면 최고의 효율을 낼 수 있다 너어무 좋다
- mutation 의 성공을 바라며 미리 UI부터 변화시켜주는 optimistic update 기능도 사용자에게 정말 좋은 경험을 제공할 수 있다.
- 전에 useQuery 편 처럼 useMutation 을 커스텀 훅으로 만드는 내용까지 시리즈로 모두 기록할 예정 !
import { useMutation } from "react-query";
// 더 많은 return 값들이 있다.
const { data, isLoading, mutate, mutateAsync } = useMutation(mutationFn, options);
mutate(variables, {
onError,
onSettled,
onSuccess,
});
Options
mutationFn (variables: TVariables) => Promise<TData>
- Required
- 비동기 작업을 수행하고 프로미스를 반환하는 함수이다. (쉽게 말해 api 요청하는 함수)
- variables 는 mutate가 전달하는 객체이다.
onSuccess, onError, onSettled
일반적으로 서버에 데이터 변경 요청을 하게 되면 변경 요청이 성공할 경우에 추가적인 액션을 할 수 있도록 코드를 작성하고는 합니다.
이런 상황은 useMutation을 사용할 때도 동일하게 적용이 됩니다.
async/await을 사용할 때는 보통 다음과 같이 결괏값이 있는지를 확인한 뒤 추가 작업을 수행할 수 있는 코드를 작성합니다.
try {
const res = await axios.post('http://localhost:8080/savePerson', person);
if(res) {
console.log('success');
}
} catch(error) {
console.log('error');
} finally {
console.log('finally');
}
하지만 useMutation을 사용하면 다음과 같이 좀더 세련되게(?) 표현해줄 수 있습니다.
// 1
const savePerson = useMutation((person: Iperson) => axios.post('http://localhost:8080/savePerson', person), {
onSuccess: () => { // 요청이 성공한 경우
console.log('onSuccess');
},
onError: (error) => { // 요청에 에러가 발생된 경우
console.log('onError');
},
onSettled: () => { // 요청이 성공하든, 에러가 발생되든 실행하고 싶은 경우
console.log('onSettled');
}
});
// 2
const savePerson = useMutation({
mutationFn: (person: Iperson) => axios.post('/savePerson', person),
onSuccess: () => { // 요청이 성공한 경우
console.log('onSuccess');
},
onError: (error) => { // 요청에 에러가 발생된 경우
console.log('onError');
},
onSettled: () => { // 요청이 성공하든, 에러가 발생되든 실행하고 싶은 경우
console.log('onSettled');
}
})
- onSuccess는 요청이 성공되었을 때 실행되는 구간입니다.
- onError는 에러가 발생될 경우 실행되는 구간입니다.
- onSettled는 finally 구문처럼 요청이 성공하든 에러가 발생되든 상관없이 마지막에 실행되는 구간입니다.
'내일배움캠프[4기_Reac트랙] > TIL' 카테고리의 다른 글
내일배움캠프 React트랙 68일차 회고 (2022.02.03) (0) | 2023.02.03 |
---|---|
내일배움캠프 React트랙 58일차 회고 (2022.01.20) (0) | 2023.01.23 |
내일배움캠프 React트랙 56일차 회고 (2022.01.17) (0) | 2023.01.18 |
내일배움캠프 React트랙 55일차 회고 (2022.01.16) (0) | 2023.01.16 |
내일배움캠프 React트랙 54일차 회고 (2022.01.13) (0) | 2023.01.16 |