Chat App (5) :  Auth 화면 구성

Sang heon lee·2022년 7월 4일
0

1. 인증과 화면 전환

  • context API 구성
    로그인한 유저의 uid 값을 받아서 전역 상태 관리
// src/contexts/User.tsx

import React, { useState, createContext } from 'react';

const UserContext = createContext({
  user: { uid: null },
  setUser: ({ uid }) => {},
});

const UserProvider = ({ children }: { children: React.ReactNode }) => {
  const [user, setUserInfo] = useState({ uid: null });
  const setUser = ({ uid }: { uid: string }) => {
    setUserInfo({ uid });
  };
  const value = { user, setUser };

  return <UserContext.Provider value={value}>{children}</UserContext.Provider>;
};

export { UserContext, UserProvider };
  • user 정보에 따라서 다른 스택이 보이게끔 설정
// src/navigations/index.tsx

import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import Auth from './Auth';
import Main from './Main';
import { UserContext, ProgressContext } from '../contexts';
import { useContext } from 'react';
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;
  • 로그인, 회원가입후 user 정보 수정
// src/screens/signin.tsx

const { setUser } = useContext(UserContext);

const _handleSinginBtnPress = async () => {
    try {
      spinner.start();
      const user = await signin({ email, password });
      setUser(user);
      // navigation.navigate('Profile', { user });
    } catch (e) {
      Alert.alert('Signin Error');
    } finally {
      spinner.stop();
    }
    // console.log('signin');
  };

// src/screens/signup.tsx
const _handleSingupBtnPress = async () => {
    try {
      spinner.start();
      const user = await signup({ name, email, password, photo });
      setUser(user);
      // navigation.navigate('Profile', { user });
    } catch (e) {
      Alert.alert('Signup Error');
    } finally {
      spinner.stop();
    }
    // console.log('signup');
  };
  • Spinner 컴포넌트 작성 : 네트워크 통신중 사용자가 다른 작업을 하지 못하도록
    -- 작업중인지 상태 관리를 위한 코드
// src/contexts/Progress.tsx
import React, { useState, createContext } from 'react';

const ProgressContext = createContext({
  inProgress: false,
  spinner: { start: () => {}, stop: () => {} },
});

const ProgressProvider = ({ children }: { children: React.ReactNode }) => {
  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 };

-- 작업중이면 보여줄 화면 작성
완전히 새로 작성하는 것이 아닌 공용 컴포넌트 사용
ActivityIndicator : https://reactnative.dev/docs/activityindicator

// src/components/Spinner.tsx
import React from 'react';
import styled from 'styled-components/native';
import { themeType } from '../theme';

interface styledPropsType {
 theme: themeType;
}

const Container = styled.View<styledPropsType>`
 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<styledPropsType>(
 ({ theme }) => ({
   size: 'large',
   color: theme.spinnerIndicator,
 }),
)``;

const Spinner = () => {
 return (
   <Container>
     <Indicator />
   </Container>
 );
};

export default Spinner;

-- 화면 우선순위 설정

// src/navigations/index.tsx

import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import Auth from './Auth';
import Main from './Main';
import { UserContext, ProgressContext } from '../contexts';
import { useContext } from 'react';
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;

-- Progress 전역 상태 관리 사용

// src/screens/signin.tsx

const { setUser } = useContext(UserContext);

const _handleSinginBtnPress = async () => {
    try {
      spinner.start();
      const user = await signin({ email, password });
      setUser(user);
      // navigation.navigate('Profile', { user });
    } catch (e) {
      Alert.alert('Signin Error');
    } finally {
      spinner.stop();
    }
    // console.log('signin');
  };

// src/screens/signup.tsx
const _handleSingupBtnPress = async () => {
    try {
      spinner.start();
      const user = await signup({ name, email, password, photo });
      setUser(user);
      // navigation.navigate('Profile', { user });
    } catch (e) {
      Alert.alert('Signup Error');
    } finally {
      spinner.stop();
    }
    // console.log('signup');
  };
profile
개초보

0개의 댓글