반응형
axios를 이용해 Backend와 API통신하면서 중간에 로딩바가 필요했다.
그런데 이걸 매번 호출마다 넣을 순 없으니 axios의 interceptors 옵션을 이용해 넣기로 했다.
우선 Loading 화면을 우선 만든다.
해당 로딩화면은 항상 최상위어야 한다. 다음처럼 컴포넌트를 만들어 Root에 추가했다.
로딩이미지는 material-ui에 있는 것을 사용했다.
https://material-ui.com/api/circular-progress/
LoadingComponent.tsx 파일 생성
import {useSelector} from "react-redux";
import CircularProgress from "@material-ui/core/CircularProgress";
import {RootState} from "../reducers";
const LoadingComponent = () => {
const {loading} = useSelector((state:RootState) => state.global);
return (
<>
{loading === false ? "" :
<>
<div className={"globalLoadingBackground"}>
</div>
<div className={"globalLoadingIcon"}>
<div className={"iconArea"}>
<CircularProgress />
</div>
</div>
</>
}
</>
)
}
export default LoadingComponent
그럼 이 컴포넌트를 _app.js 파일에 추가한다
<LoadingComponent /> 추가
import LoadingComponent from "../container/LoadingComponent";
...
return (
<Provider store={store}>
<div>
<CookiesProvider>
// 이부분에 추가
<LoadingComponent />
<AppLayout>
<Component {...pageProps}/>
</AppLayout>
</CookiesProvider>
</div>
</Provider>
)
...
redux에 로딩관련 action 을 등록한다.
(여기선 immer를 적용했기에 draft 명령어를 사용했다.)
import produce from "immer";
export const initialState = {
loading: false
}
export const GLOBAL_LOADING = "LOADING"
export const GLOBAL_LOADED = "LOADED"
const reducer = (state = initialState, action) => {
return produce(state, (draft) => {
switch (action.type) {
case GLOBAL_LOADING: {
draft.loading = true
break
}
case GLOBAL_LOADED: {
draft.loading = false
break;
}
}
})
}
위 설정을 완료한 후 요청할때마다 action을 호출하면 된다.
그럼 이제 axios를 설정하자. API를 요청할 때, 로딩바를 호출, 끄면 된다.
내 경우 Layout을 구성하는 페이지에다 담았는데 (_app.js 안에 컴포넌트를 감싸는 부모 컴포넌트) 필요에 따라 다른곳에 넣어도 된다.
AppLayout.js
const AppLayout = () => {
...
const dispatch = useDispatch();
useEffect(() => {
axios.interceptors.request.use(function (config) {
// 로딩 호출
dispatch({
type: GLOBAL_LOADING
})
return config;
}, function (error) {
// 실패 시 로딩창 종료
dispatch({
type: GLOBAL_LOADED
})
return Promise.reject(error);
})
axios.interceptors.response.use((config) => {
// 완료 시 로딩창 종료
dispatch({
type: GLOBAL_LOADED
})
return config;
},(error) => {
// 실패 시 로딩창 종료
dispatch({
type: GLOBAL_LOADED
})
return Promise.reject(error)
})
}, [])
...
}
axios 옵션 중 interceptors 를 보면 request와 response 가 있는데, request는 호출할 때, response는 받을때를 의미한다. 각각을 1번만 설정하면 앞으로 API를 호출할때마다 해당 로딩 action을 호출한다.
끝.
반응형
'공부 > 프로그래밍' 카테고리의 다른 글
[retrofit, gson] Expected BEGIN_OBJECT but was STRING 에러 해결(String -> LocalDate) (1) | 2021.01.18 |
---|---|
[jpa] 쿼리 로그 설정 (0) | 2021.01.15 |
[springboot] 자주쓰는 정보 파라미터에 설정해 자동 주입하여 받기(resolver 사용) (0) | 2021.01.11 |
[aws] aws cli로 s3 파일 삭제(console에서 파일삭제 실패 시-파일명 한글일 경우 실패함) (1) | 2021.01.08 |
[nginx] aws에 nginx설치 및 멀티도메인 설정(reverse-proxy) (0) | 2021.01.06 |
댓글