매번 Loading Modal Component를 만들 순없기에
Context로 전역으로 Loading화면을 띄울 수 있게 만들자!
근데 Loading은 자주 변동이 일어나는 변수인데 context로 저장하는 것이 좋은 방안인지 잘 모르겠다.
기본 사용법은 useConText를 참고하도록..
import React, { createContext, useContext, useMemo, useReducer } from "react";
import { ILoadingContext, LoadingReduce } from "@types";
import LoadingModal from "../components/LoadingModal";
const LoadingContext = createContext<ILoadingContext | null>(null);
const **useLoadingContext** = () => {
const context = useContext(LoadingContext);
if (!context)
throw new Error('Cannot find AuthContext');
return context;
}
const LoadingContextProvider = ({ children }: { children: JSX.Element }) => {
const **reduce**: LoadingReduce = (_, action) => {
switch (action.type) {
case 'START':
return {
isLoading: true,
};
case 'END':
return {
isLoading: false,
}
}
}
const [loading, dispatch] = useReducer(reduce, {
isLoading: false,
});
const **useLoading** = useMemo(() => ({
startLoading: () => {
dispatch({ type: "START" });
},
endLoading: () => {
dispatch({ type: "END" })
}
}), []);
return (
<LoadingContext.Provider value={{ loading, useLoading }}>
**<LoadingModal loading={loading.isLoading} />**
{children}
</LoadingContext.Provider>
)
}
export { LoadingContext, useLoadingContext, LoadingContextProvider }
Context내부에 LoadingModal를 둬서 다른 곳에서 별도로 선언해줄 필요가 없다
type Loading = { isLoading: boolean }
type LoadingReduce = (state: Loading, action: { type: 'START' | 'END' }) => Loading
interface ILoadingContext {
loading: Loading,
useLoading: {
startLoading: () => void;
endLoading: () => void;
}
}
react-native-modal
사용
import React from 'react'
import { Image } from 'react-native';
import Modal from 'react-native-modal';
import { loadingPath } from '../atoms/paths';
const loadingGif = [...Object.values(loadingPath)]
interface Props {
loading: boolean;
}
const LoadingModal = ({ loading }: Props) => {
const gifUri = loadingGif[Math.floor(Math.random() * loadingGif.length)]
return (
<Modal
isVisible={loading}
style={{ justifyContent: "center", alignItems: "center" }}
animationIn={'**tada**'}
animationInTiming={1000}
animationOut={'**slideOutRight**'}
animationOutTiming={1000}
backdropOpacity={0.8}
>
<Image
source={gifUri}
style={{ width: "20%", aspectRatio: 1, resizeMode: "**contain**" }} />
</Modal>
)
}
export default LoadingModal