TIL

<TIL> React-Native 로그인 플로우, 중첩 router - Trello(5)

버퀴 2020. 3. 20. 21:46

1. 로그인 플로우

 

App.js에서 AsyncSotrage에 저장된 토큰이 있는지 확인


<있다>                                         <없다>

 

                                         로그인 화면 거치지 않고                    로그인, 회원가입 할 수 있는                                        

                   바로 메인 화면으로 이동                              페이지로 이동                            

 

맨 상위 페이지 App.js

import React, { Component } from 'react';
import 'react-native-gesture-handler';
import { AsyncStorage } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { createDrawerNavigator } from '@react-navigation/drawer';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import Main from './components/Main';
import Board from './components/Board';
import Card from './components/Card';
import Login from './components/FirstPages/LoginPage';
import Signup from './components/FirstPages/SignupPage';
import UserPage from './components/UserPage';
import First from './components/FirstPages/FirstPage';

const Stack = createStackNavigator();
const Drawer = createDrawerNavigator();

export default class App extends Component {
  constructor() {
    super();
    this.state = {
      Login: false,
    };
    this.ChangeState = this.ChangeState.bind(this);
  }

  async ChangeState() {
    if (await AsyncStorage.getItem('user_Token')) {
      this.setState({
        Login: true,
      });
    } else {
      this.setState({
        Login: false,
      });
    }
  }

  render() {
    this.ChangeState();
    return (
      <NavigationContainer>
      <SafeAreaProvider>
        { this.state.Login ? (
           <Main/>
        ) : (
          <Stack.Navigator screenOptions={{
            headerShown: false,
          }}>
            <>
              <Stack.Screen name="First Screen" component={First} />
              <Stack.Screen name="Signup Screen" component={Signup} />
              <Stack.Screen name="Login Screen" component={Login} />
            </>
          </Stack.Navigator>
        )}
      </SafeAreaProvider>
      </NavigationContainer>
    );
  }
}

함수 안에서 token이 존재 하는지 안하는지를 if문으로 확인

AsyncStorage에 값을 가져온 getItem은 pending값으로 나오기 때문에 await을 붙여줘 가져와야 합니다.

 

token이 존재하면 ->  state.Login의 값을 true로 변경

token이 존재 하지 않으면 ->  state.Login의 값을 false로 변경

 

그 함수(ChangeState)를 return 앞에서 실행하면서 token값을 확인하여 state값을 변화시킵니다.

로그인이 되어있는 상태(token 값이 있는 상태)면 메인 화면으로 바로 갈 수 있고 아니면 로그인 화면으로 가게 작동이 됩니다.

 

2. Drawer안에 Stack router적용

로그인이 되어있는 모든 화면에는 drawer가 작동이 됩니다.

import React, { Component } from 'react';
import 'react-native-gesture-handler';
import { AsyncStorage } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { createDrawerNavigator } from '@react-navigation/drawer';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
import Main from './components/Main';
import Board from './components/Board';
import Card from './components/Card';
import Reducer from './components/Redux/Reducer';
import Login from './components/FirstPages/LoginPage';
import Signup from './components/FirstPages/SignupPage';
import UserPage from './components/UserPage';
import First from './components/FirstPages/FirstPage';

const Stack = createStackNavigator();
const Drawer = createDrawerNavigator();
const store = createStore(Reducer);

function StackHome() {
  return (
      <Stack.Navigator>
        <Stack.Screen name="Home" component={Main} />
        <Stack.Screen name="Board" component={Board} />
        <Stack.Screen name="Card" component={Card} />
      </Stack.Navigator>
  );
}
function BoardStack() {
  return (
    <Stack.Navigator>
      <Stack.Screen name="Board" component={Board} />
      <Stack.Screen name="Card" component={Card} />
    </Stack.Navigator>
  );
}

export default class App extends Component {
  constructor() {
    super();
    this.state = {
      Login: false,
    };
    this.ChangeState = this.ChangeState.bind(this);
  }

  async ChangeState() {
    if (await AsyncStorage.getItem('user_Token')) {
      this.setState({
        Login: true,
      });
    } else {
      this.setState({
        Login: false,
      });
    }
  }

  render() {
    this.ChangeState();
    return (
      <NavigationContainer>
      <SafeAreaProvider>
        <Provider store={store}>
        { this.state.Login ? (
            <Drawer.Navigator>
                <Drawer.Screen name="Main" component={StackHome} />
                <Drawer.Screen name="Board" component={BoardStack} />
                <Drawer.Screen name="UserInfo" component={UserPage} />
            </Drawer.Navigator>
        ) : (
          <Stack.Navigator screenOptions={{
            headerShown: false,
          }}>
            <>
              <Stack.Screen name="First Screen" component={First} />
              <Stack.Screen name="Signup Screen" component={Signup} />
              <Stack.Screen name="Login Screen" component={Login} />
            </>
          </Stack.Navigator>
        )}
        </Provider>
      </SafeAreaProvider>
      </NavigationContainer>
    );
  }
}
// redux로 토큰을 저장 유무를 판단하여 로그인화면을 보여줄지 메인을 보여줄지 판단
//

 

 

HomeStack 스텍에는 board와 Main , Card로 이동 할 수 있습니다. 

그래서 3 화면이 스택 으로 묶인 함수로 만듭니다.

 

drawer Board에서 이동한 board화면의 스텍은 Board와 Card로만 구성하였습니다.

그 함수들을 component에 넣어주면 됩니다.