FRONT/리액트네이티브

react native typescript에서 navigation 으로 화면 전환 구현하기

혀니리리 2023. 5. 5. 16:29
728x90

 

typescript형태로 app.tsx가 빌드가 되었어서.. navigation도 그에 따라 기존의 App.js 구현 때와는 다르게 구현해야 했다.

https://benjaminwoojang.medium.com/react-navigation-with-typescript-270dfa8d5cad

 

React Navigation with Typescript

React Navigation is a library that helps with routing and navigation.

benjaminwoojang.medium.com

구현에는 이 글이 가장 많은 도움이 되었다. 

 

왜인지는 모르겠지만 typescript는 javascript와는 달리 navigation.navigate 를 바로 쓸 수 없었고,

각 Stack의 형식을 지정해줘야 하는 것 같았다.

 

각 코드는 이러하다.

import React from 'react';
import {NavigationContainer} from '@react-navigation/native';
import {createStackNavigator} from '@react-navigation/stack';
import MainScreen from './screens/main';
import AuthScreen from './screens/auth';
import {RootStackParamList} from './screens/RootStackPrams';

const Stack = createStackNavigator<RootStackParamList>();

export default function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen name="Main" component={MainScreen} />
        <Stack.Screen name="Auth" component={AuthScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

App.tsx

 

export type RootStackParamList ={
    Main:undefined;
    Auth:undefined;
}

RootStackPrams.tsx

 

import {useNavigation} from '@react-navigation/native';
import React from 'react';
import {View, Text, Button} from 'react-native';
import {StackNavigationProp} from '@react-navigation/stack';
import {RootStackParamList} from '../RootStackPrams';

type mainScreenProp = StackNavigationProp<RootStackParamList, 'Main'>;

function AuthScreen() {
  const navigation = useNavigation<mainScreenProp>();
  return (
    <View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
      <Text>Auth Screen</Text>
      <Button title="Login" onPress={() => navigation.navigate('Auth')} />
    </View>
  );
}

export default AuthScreen;

screens/auth/index.tsx

 

import React from 'react';
import type {PropsWithChildren} from 'react';
import {View, Text, StyleSheet, SafeAreaView, StatusBar, ScrollView} from 'react-native';
import {useNavigation} from '@react-navigation/native';
import {StackNavigationProp} from '@react-navigation/stack';
import {RootStackParamList} from '../RootStackPrams';
import { TouchableOpacity } from 'react-native-gesture-handler';

type SectionProps = PropsWithChildren<{
    title: string;
  }>;
  
  function Section({children, title}: SectionProps): JSX.Element {
    return (
      <View style={styles.sectionContainer}>
        <Text
          style={[styles.sectionTitle,{color: 'black'}]}>
          {title}
        </Text>
        <Text style={[styles.sectionDescription,{color: 'black'}]}>
          {children}
        </Text>
      </View>
    );
  }


type authScreenProp = StackNavigationProp<RootStackParamList, 'Auth'>;

function MainScreen() {
  const navigation = useNavigation<authScreenProp>();

  const backgroundStyle = {
    backgroundColor: 'darkgray',
    flex: 1
  };

  return (
    <SafeAreaView style={backgroundStyle}>
        <StatusBar barStyle='dark-content'/>
        <ScrollView contentInsetAdjustmentBehavior="automatic" style={backgroundStyle}>
            <View style={{ backgroundColor: 'darkgray'}}
                accessible={true}>
                    <TouchableOpacity onPress={() => navigation.navigate('Auth')}>
                    <Section title="뉴스"></Section>
                    </TouchableOpacity>
                    <TouchableOpacity onPress={() => navigation.navigate('Auth')}>
                    <Section title="커피빈"></Section>
                    </TouchableOpacity>
                    <TouchableOpacity onPress={() => navigation.navigate('Auth')}>
                    <Section title="쿠팡"></Section>
                    </TouchableOpacity>
                    <TouchableOpacity onPress={() => navigation.navigate('Auth')}>
                    <Section title="도서"></Section>
                    </TouchableOpacity>
                    <TouchableOpacity onPress={() => navigation.navigate('Auth')}>
                    <Section title="마켓"></Section>
                    </TouchableOpacity>
                    <TouchableOpacity onPress={() => navigation.navigate('Auth')}>
                    <Section title="꽃집"></Section>
                    </TouchableOpacity>
                    <TouchableOpacity onPress={() => navigation.navigate('Auth')}>
                    <Section title="배달"></Section>
                    </TouchableOpacity>
            </View>
        </ScrollView>
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
    sectionContainer: {
      marginTop: 20,
      paddingHorizontal: 30,
      borderBottomColor: 'black',
      borderBottomWidth: 1
    },
    sectionTitle: {
      fontSize: 24,
      fontWeight: '600',
    },
    sectionDescription: {
      marginTop: 10,
      fontSize: 18,
      fontWeight: '400',
    },
    highlight: {
      fontWeight: '700',
    },
  });

export default MainScreen;

screens/main/index.tsx

 

 

기본적으로 위에 문서를 참고하되, main에 해당하는 부분만 button -> touchableOpacity로 전환하여 클릭 시 화면이 전환되도록 하였다.

앞으론 typescript의 더욱 자세한 이해와 코드 네임 변경, 넘어간 후의 배경 전환이 필요하다.

728x90