로그인하거나 회원가입 통신할때 사용자가 다른 행동을 하지 않도록 Spinner 컴포넌트를 만드려고 한다.
공식문서 : https://reactnative.dev/docs/activityindicator
z-index: 2;를 설정해준다. import React from 'react';
import styled from 'styled-components/native';
const Container = styled.View`
position: absolute;
z-index: 2; /** 컴포넌트가 최상위에 위치하도록 */
opacity: 0.3;
width: 100%;
height: 100%;
justify-content: center;
background-color: ${({ theme }) => theme.spinnerBackground};
`;
const Indicator = styled.ActivityIndicator.attrs(({ theme }) => ({
size: 'large',
color: theme.spinnerIndicator,
}))``;
const Spinner = () => {
return (
<Container>
<Indicator />
</Container>
);
};
export default Spinner;
import { NavigationContainer } from '@react-navigation/native';
import React, { useContext } from 'react';
import Auth from './Auth';
import { UserContext } from '../contexts';
import Main from './Main';
/**어떤 화면이든 가리도록 navigations의 index.js에서 스피너 컴포넌트 사용 */
import { Spinner } from '../components';
const Navigation = () => {
const { user } = useContext(UserContext);
return (
<NavigationContainer>
{user.uid ? <Main /> : <Auth />}
<Spinner />
</NavigationContainer>
);
};
export default Navigation;

//Spinner 컴포넌트의 렌더링 여부를 결정
import React , {useState, createContext} from 'react';
const ProgressContext = createContext({
inProgress : false,
spinner: {start:()=>{}, stop: ()=>{}}
});
const ProgressProvider =({children}) =>{
const [inProgress, setInProgress] = useState(false);
const spinner ={
start : () => setInProgress(true),
stop : () => setInProgress(false)
};
const value = {inProgress, spinner}
return (
<ProgressContext.Provider value={value}>
{children}
</ProgressContext.Provider>
)
}
export {ProgressContext, ProgressProvider}
import { UserContext, ProgressContext } from '../contexts';
const { spinner } = useContext(ProgressContext);
const _handleSigninBtnPress = async () => {
try {
spinner.start();
const user = await signin({ email, password });
setUser(user);
} catch (e) {
Alert.alert('Signin Error', e.message);
} finally {
spinner.stop();
}
};
import { UserContext, ProgressContext } from '../contexts';
const { spinner } = useContext(ProgressContext);
const _handleSignupBtnPress = async () => {
try {
spinner.start();
const user = await signup({ name, email, password, photo });
setUser(user);
} catch (e) {
Alert.alert('Signup Error', e.message);
} finally {
spinner.stop();
}
};
import { NavigationContainer } from '@react-navigation/native';
import React, { useContext } from 'react';
import Auth from './Auth';
import { UserContext, ProgressContext } from '../contexts';
import Main from './Main';
import { Spinner } from '../components';
const Navigation = () => {
const { user } = useContext(UserContext);
const { inProgress } = useContext(ProgressContext);
return (
<NavigationContainer>
{user.uid ? <Main /> : <Auth />}
{inProgress && <Spinner />}
</NavigationContainer>
);
};
export default Navigation;
이렇게 코드를 작성해주니 로그인 시도시 spinner이 잘 돌아간다.
