Project 에 axios dependencies 추가
yarn add axios
사용하는 모듈에서 바로 axios 를 사용하여 호출하는 것 보다는 특정 Service 모듈을 만들어 호출하는 것이 API error, retry 처리에 용이함
import axios, { AxiosRequestConfig, CancelTokenSource } from "axios";
class Service {
get(url: string, params?: { [key: string]: string | number }): Promise<any> {
return axiosApi.get(url, {
params: params,
cancelToken: cancelSource.token,
});
}
}
React 생명주기 또는 sideEffect 생명주기를 위해 API cancel 도 추가
import axios, { AxiosRequestConfig, CancelTokenSource } from "axios";
const defaultConfig: AxiosRequestConfig = {};
const axiosApi = axios.create(defaultConfig);
type Executor<T> = (
resolve: (value: T | PromiseLike<T>) => void,
reject: (reason?: any) => void
) => void;
export class ApiPromise<T> extends Promise<T> {
private $source: CancelTokenSource;
constructor(executor: Executor<T>, cancelSource: CancelTokenSource) {
super(executor);
this.$source = cancelSource;
}
public cancel(msg?: string) {
this.$source.cancel(msg);
}
get source(): CancelTokenSource {
return this.$source;
}
}
class Service {
get(url: string, params?: { [key: string]: string | number }): ApiPromise<any> {
const cancelSource = axios.CancelToken.source();
const api = axiosApi.get(url, {
params: params,
cancelToken: cancelSource.token,
});
return new ApiPromise((resolve, reject) => {
api.then((resp) => {
resolve(resp);
}).catch((error) => {
reject(error);
});
}, cancelSource);
}
}
Promise의 executor 타입을 선언후 ApiPromise class 정의
class constructor 두번째 인자로 axios의 cancelSource 를 받는다
type Executor<T> = (
resolve: (value: T | PromiseLike<T>) => void,
reject: (reason?: any) => void
) => void;
export class ApiPromise<T> extends Promise<T> {
private $source: CancelTokenSource;
constructor(executor: Executor<T>, cancelSource: CancelTokenSource) {
super(executor);
this.$source = cancelSource;
}
public cancel(msg?: string) {
this.$source.cancel(msg);
}
get source(): CancelTokenSource {
return this.$source;
}
}
기존 Service class 코드에 ApiPromise 로 wappring 하여 전달
class Service {
get(url: string, params?: { [key: string]: string | number }): ApiPromise<any> {
const cancelSource = axios.CancelToken.source();
const api = axiosApi.get(url, {
params: params,
cancelToken: cancelSource.token,
});
return new ApiPromise((resolve, reject) => {
api.then((resp) => {
resolve(resp);
}).catch((error) => {
reject(error);
});
}, cancelSource);
}
}
이제 사용
const [user, setUser] = useState<User | null | undefined>();
useEffect(() => {
const api = APIService.get(`user/${id}`);
api.then((user) => {
setUser(user);
}).catch((error) => {
setUser(null);
});
return () => {
api.cancel();
};
}, [id]);
id 가 없데이트 될 때마다 clear up 에서 api cancel 해줌
'개발 > React' 카테고리의 다른 글
React Scripts 4.x -> 5.x 마이그레이션 (0) | 2023.10.26 |
---|---|
React Chunk hash를 제거 해보자 (0) | 2022.04.15 |
axios + rxjs 를 이용한 API retry policy (0) | 2021.09.26 |
react-script 업데이트 IE11 동작하지 않는 문제 (0) | 2020.09.18 |
React 에서 jest 를 이용한 API test 시 timeout 변경 (0) | 2020.09.18 |