Stack Navigation 1 - 화면 이동

cooking_123·2024년 3월 14일

React Native TIL

목록 보기
19/30

Stack Navigation

일반적인 화면 이동 네비게이션. 스택형식을 띄운다. 예를 들어 홈 화면에서 목록 화면으로 이동하고 채팅화면으로 이동하고 다시 나와 목록화면으로 가는 것을 아래 사진으로 표현

1. 설치

$ npm install @react-navigation/stack

2. 사용

  • 설치된 라이브러리에서 제공하는 CreateStackNavigator을 이용해서 stack 내비게이션을 생성해야 한다.
const Stack =  CreateStackNavigator()
  • 생성된 stack 내비게이션에는 Navigator 컴포너너트Screen 컴포넌트가 있다.
const Stack = CreateStackNavigator()

  <Stack.Navigator>
  	<Stack.Screen>
    </Stack.Screen>
  </Stack.Navigator>

3. Stack Navigation 설정 (실습)

1. navigation 폴더를 만들어서 네이게이션 파일을 관리

화면에서 사용할 Home, List, Chat 컴포넌트를 모두 screen 폴더 안에 import해야 하는데 번거로우니 index.js 파일을 만들어서 Home, List, Chat 컴포넌트 모두를 모아서 import 해둔다.

//index.js
import Home from './Home';
import List from './List';
import Chat from './Chat';

export { Home, List, Chat };


### 2. stack navigation 이용
```js
//navigations/stack.js
import React from 'react';
import { createStackNavigator } from '@react-navigation/stack';
import { Home, List, Chat } from '../screens';

// createStackNavigator을 이용해 stack navigation을 생성
const Stack = createStackNavigator();

const StackNav = () => {
    return (
        <Stack.Navigator>
            {/* screen 네임 속성은 screen 컴포넌트를 식별하기 위한 id처럼 사용되기때문에
            중복되지 않도록 작성해야하고 화면을 명확하게 구분할 수 있도록 이름을 작성하는 것을 추천 */}
            <Stack.Screen name='Home' component={Home} />
            <Stack.Screen name='List' component={List} />
            <Stack.Screen name='Chat' component={Chat} />
        </Stack.Navigator>
    );
};

export default StackNav;

3. 비슷한 코드 모아서 관리

코드를 간략하게 하고 비슷한 성격의 코드를 모아서 관리

//navigations/index.js
import { NavigationContainer } from '@react-navigation/native';
import StackNav from './Stack';
import React from 'react';

const Navigation = () => {
    return (
        <NavigationContainer>
            <StackNav />
        </NavigationContainer>
    );
};

export default Navigation;

3.최상위 컴포넌트 App.js에 내비게이션 컴포넌트 사용

import React from 'react';
import Navigation from './navigations';

export default function App() {
    return (
        <Navigation />
    );
}

4. Stack Navigation - 화면이동(실습)

1. 첫번째 컴포넌트를 첫화면으로 사용

Stack Navigation에서는 navigation 컴포넌트의 자식 컴포넌트 중 첫번째 컴포넌트를 첫화면으로 사용한다.

예시1.

//navigations/Stack.js
        <Stack.Navigator>
            <Stack.Screen name='Chat' component={Chat} />
            <Stack.Screen name='List' component={List} />
            <Stack.Screen name='Home' component={Home} />
        </Stack.Navigator>

예시2.

//navigations/Stack.js
        <Stack.Navigator>
            <Stack.Screen name='List' component={List} />
            <Stack.Screen name='Chat' component={Chat} />
            <Stack.Screen name='Home' component={Home} />
        </Stack.Navigator>

2. initialRouteName 속성

initialRouteName 속성을 사용하면 컴포넌트의 순서와 상관없이 첫번째 화면으로 이동할 screen 커모넌트를 지정할 수 있다.

//navigations/Stack.js
const StackNav = () => {
    return (
        <Stack.Navigator initialRouteName='Home'>
            <Stack.Screen name='Chat' component={Chat} />
            <Stack.Screen name='List' component={List} />
            <Stack.Screen name='Home' component={Home} />
        </Stack.Navigator>
    );
};

주의 : initialRouteName에 설정하는 값은 screen 컴포넌트의 name으로 설정된 값들 중 하나여야 한다. initialRouteName에 설정된 값과 동일한 이름의 screen 컴포넌트를 찾지 못할 경우 첫 번째 화면은 첫번쨰 자식 컴포넌트로 사용된 screen 컴포넌트가 된다.

//navigations/Stack.js
const StackNav = () => {
    return (
        <Stack.Navigator initialRouteName='Home2'>
            <Stack.Screen name='Chat' component={Chat} />
            <Stack.Screen name='List' component={List} />
            <Stack.Screen name='Home' component={Home} />
        </Stack.Navigator>
    );
};

3. 화면 이동 - Navigation prop 사용

공식문서 : https://reactnavigation.org/docs/navigation-prop/

  • screen 컴포넌트에서 컴포넌트로 지정되어 화면으로 사용되는 컴포넌트에는 props로 항상 navigationroute가 전달된다. 그 중 네비게이션에는 다양한 기능을 제공하고 있는데 그 중 navigate 함수를 사용하면 원하는 화면으로 이동이 가능합니다.

예시 1. props로 전달되는 네비게이션을 받아서 버튼을 클릭하면 list라는 이름을 가진 화면으로 이동

네비게이트에 전달되는 화면의 이름은 screen 컴포넌트의 name으로 작성된 이름을 사용해야 한다.

//screens/Home.js
const Home = ({ navigation }) => {
    return (
        <Container>
            <StyledText>Home</StyledText>
            <Button title='List' onPress={() => navigation.navigate('List')} />
        </Container>
    );
};
  • navigate 함수의 두번쨰 파라미터에 전달하고 싶은 데이터를 입력하면 화면 이동과 함께 데이터를 전달할 수 있고 받는 쪽에서는 routeparams로 담겨져서 들어온다.

예시 2. props로 route 전달

List.js


const items = [
    { id: 1, name: 'React Native' },
    { id: 2, name: 'Expo' },
    { id: 3, name: 'React Navigation' },
];

const List = ({ navigation }) => {
    return (
        <Container>
            <StyledText>List</StyledText>
            {items.map(({ id, name }) => (
                <Button key={id} title={name} 
				onPress={() => navigation.navigate('Chat', { id, name })} />
            ))}
        </Container>
    );
};

Chat.js

const Chat = ({ route }) => {
    return (
        <Container>
            <StyledText>Chat</StyledText>
            <StyledText>{route.params.id}</StyledText>
            <StyledText>{route.params.name}</StyledText>
            <Button title='Home' />
        </Container>
    );
};


이동

4. reset 함수

  • 위의 사진을 보면 뒤로가기 버튼을 볼 수 있는데 화면을 이동하면서 화면이 쌓이면 뒤로가기 버튼을 이용해 화면을 걷어내고 이전 화면으로 이동할 수 있다.
  • 만약 쌓여있는 화면들을 초기화하고 원하는 위치로 이동하고 싶은 경우에는 navigation에서 제공하는 reset함수를 이용하면 된다.
  • 주의 : reset 함수를 이용할때는 객체를 전달해야하고 route라는 키의 화면 이름을 객체로 갖고 있는 배열을 전달해야 한다는 것이다.

Chat.js

const Chat = ({ navigation, route }) => {
    return (
        <Container>
            <StyledText>Chat</StyledText>
            <StyledText>{route.params.id}</StyledText>
            <StyledText>{route.params.name}</StyledText>
            <Button title='Home' onPress={() => navigation.reset({ routes: [{ name: 'Home' }] })} />
        </Container>
    );
};

예시 1. 만약 List 화면으로 리셋하고 싶다면

만약 밑에 쌓여있는 화면없이 특정 화면만 스택에 있기를 원한다면 전달되는 배열에 리스트만 전달하면 된다. 아래 사진을 보면 reset 함수에 List만 전달이 되면 헤더에 뒤로가기 버튼이 보이지 않는다.

Chat.js

const Chat = ({ navigation, route }) => {
    return (
        <Container>
            <StyledText>Chat</StyledText>
            <StyledText>{route.params.id}</StyledText>
            <StyledText>{route.params.name}</StyledText>
            <Button title='Home' onPress={() => navigation.reset({ routes: [{ name: 'List' }] })} />
        </Container>
    );
};

예시 2. 만약 이전화면으로 Home화면이 있는 상태의 List 화면으로 이동하고 싶다면 배열의 순서대로 Home 리스트를 전달하면 된다.

Chat.js

const Chat = ({ navigation, route }) => {
    return (
        <Container>
            <StyledText>Chat</StyledText>
            <StyledText>{route.params.id}</StyledText>
            <StyledText>{route.params.name}</StyledText>
            <Button title='Home' onPress={() => navigation.reset({ routes: [{ name: 'Home' }, { name: 'List' }] })} />
        </Container>
    );
};

5. cardStyle을 지정하여 배경색 변경 -> options

stack.js

const StackNav = () => {
    return (
        <Stack.Navigator initialRouteName='Home'>
            <Stack.Screen name='Chat' component={Chat} />
            <Stack.Screen name='List' component={List} />
            <Stack.Screen name='Home' component={Home} 
			options={{ cardStyle: { backgroundColor: '#ffffff' } }} />
        </Stack.Navigator>
    );
};

변경전

변경후

5. cardStyle을 지정하여 배경색 변경 -> Navigator컴포넌트에서 screenOptions 설정

만약 특정 화면의 배경색만 다르게 해야 하는 상황이 아니라면 모든 배경색을 통일하려면 Navigator컴포넌트에서 screenOptions 설정

stack.js

const StackNav = () => {
    return (
        <Stack.Navigator initialRouteName='Home' 
      	screenOptions={{ cardStyle: { backgroundColor: '#ffffff' } }}>
            <Stack.Screen name='Chat' component={Chat} />
            <Stack.Screen name='List' component={List} />
            <Stack.Screen name='Home' component={Home} />
        </Stack.Navigator>
    );
};

0개의 댓글