Navigations¶

Navigator를 사용한다.

react-navigation버전 3.x을 사용합니다.

설치합니다.

npm install --save react-navigation

Expo를 사용하지 않으면 다음 모듈 react-native-gesture-handler를 설치해야 합니다.

npm install --save react-native-gesture-handler

그리고 링크를 해주어야 합니다.

react-native link react-native-gesture-handler

안드로이드는 android\app\src\main\java\com\프로젝트이름\MainActivity.javaMainActivity.java에 다음과 같은 것을 추가해야 합니다.

package com.weatherproject;

import com.facebook.react.ReactActivity;
// 아래 3줄 import 구문 추가
import com.facebook.react.ReactActivityDelegate;
import com.facebook.react.ReactRootView;
import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView;

public class MainActivity extends ReactActivity {

    /**
     * Returns the name of the main component registered from JavaScript.
     * This is used to schedule rendering of the component.
     */
    @Override
    protected String getMainComponentName() {
        return "WeatherProject";
    }

    // 아래 ReactActivityDelegate 메소드 추가
    @Override
    protected ReactActivityDelegate createReactActivityDelegate() {
      return new ReactActivityDelegate(this, getMainComponentName()) {
        @Override
        protected ReactRootView createRootView() {
         return new RNGestureHandlerEnabledRootView(MainActivity.this);
        }
      };
    }
}

App.js 파일에 다음과 같이 넣어줘야 합니다.

// In App.js in a new project

import React from "react";
import { View, Text } from "react-native";
import { createStackNavigator, createAppContainer } from "react-navigation";

class HomeScreen extends React.Component {
  render() {
    return (
      <View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
        <Text>Home Screen</Text>
      </View>
    );
  }
}

const AppNavigator = createStackNavigator({
  Home: {
    screen: HomeScreen
  }
});

export default createAppContainer(AppNavigator);

StackNavigator는 스크린 스택 사이를 옮길 수 있게 합니다. TabNavigator, DrawerNavigator등도 있습니다. 이러한 네비게이터들을 하나의 앱에서 여러 개를 동시에 사용할 수 있습니다.

스크린을 추가하려면 컴포넌트를 하나 더 만들고 다음과 같이 추가하면 됩니다.

// HomeScreen 외 다른 코드가 여기에 있어야 합니다.

class DetailsScreen extends React.Component {
  render() {
    return (
      <View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
        <Text>Details Screen</Text>
      </View>
    );
  }
}

const AppNavigator = createStackNavigator(
  {
    Home: HomeScreen,
    Details: DetailsScreen
  },
  {
    initialRouteName: "Home"
  }
);

스크린 이동¶

홈 스크린에서 디테일 스크린으로 이동하는 방법은 다음과 같습니다.

class HomeScreen extends React.Component {
  render() {
    return (
      <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
        <Text>Home Screen</Text>
        <Button
          title="Go to Details"
          onPress={() => this.props.navigation.navigate('Details')}
        />
      </View>
    );
  }
}

자식 컴포넌트에서 스크린 이동¶

자식 컴포넌트에서 네비게이션을 사용하려면 부모 컴포넌트의 props에 navigation을 넣어줘야 합니다.

// 부모 컴포넌트
const Parent = (props) => {
  return (
    <View>
      <Text>Parent Component</Text>
        <Child
          navigation={props.navigation} // 자식 컴포넌트에 props로 넘김.
          destination="pagetwo" text="To page 2"
        />
    </View>
  )
}

const Child = (props) => {
  return (
    <TouchableOpacity
      onPress={() => props.navigation.navigate(props.destination)} // 부모에게서 받은 props를 사용.
    >
      <Text>{props.text}>>></Text>
    </TouchableOpacity>
  );
}

예제¶

This is a 3 page example that shows how to pass the navigate function to a child component and how to customize props send to screens from within the StackNavigator. 1

// subcomponent ... receives navigate from parent
const Child = (props) => {
    return (
        <TouchableOpacity
            onPress={() => props.navigate(props.destination) }>
            <Text>{props.text}>>></Text>
        </TouchableOpacity>
    );
}
// receives navigation from StackNavigator
const PageOne = (props) => {
    return (
        <View>
            <Text>Page One</Text>
            <Child
                navigate={props.navigation.navigate}
                destination="pagetwo" text="To page 2"/>
        </View>
    )
}
// receives custom props AND navigate inside StackNavigator
const PageTwo = (props) => (
    <View>
        <Text>{props.text}</Text>
        <Child
            navigate={props.navigation.navigate}
            destination="pagethree" text="To page 3"/>
    </View>
);
// receives ONLY custom props (no nav sent) inside StackNAvigator
const PageThree = (props) => <View><Text>{props.text}</Text></View>

export default App = StackNavigator({
    pageone: {
        screen: PageOne, navigationOptions: { title: "One" } },
    pagetwo: {
        screen: (navigation) => <PageTwo {...navigation} text="Page Deux" />,
        navigationOptions: { title: "Two" }
    },
    pagethree: {
        screen: () => <PageThree text="Page III" />,
        navigationOptions: { title: "Three" }
    },
});

라우트에 매개변수 넘기기 3¶

라우트 사이에 이동할 때에 데이터를 넘겨주는 방법에 대해서 알아봅니다. 다음과 같이 두 단계를 이용합니다.

  1. navigation.navigate 함수를 호출할 때 첫번째 인자는 라우트 이름이고, 두 번째 인자로 매개변수를 object 형식으로 넘겨주는 것입니다.:

    this.props.navigation.navigate('RouteName', { /* params go here */ })
    
  2. 스크린 컴포넌트에서 매개변수를 다음과 같이 읽습니다.:

    this.props.navigation.getParam(paramName, defaultValue).
    

매개변수를 JSON-serializable 형식으로 넘겨주는 것을 추천합니다. 그래야만 나중에 상태 저장이나 깊은 링크를 가진 스크린 컴포넌트들을 이용할 때 제대로 작동할 것입니다.

class HomeScreen extends React.Component {
  render() {
    return (
      <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
        <Text>Home Screen</Text>
        <Button
          title="Go to Details"
          onPress={() => {
            /* 1. Navigate to the Details route with params */
            this.props.navigation.navigate('Details', {
              itemId: 86,
              otherParam: 'anything you want here',
            });
          }}
        />
      </View>
    );
  }
}

class DetailsScreen extends React.Component {
  render() {
    /* 2. Get the param, provide a fallback value if not available */
    const { navigation } = this.props;
    const itemId = navigation.getParam('itemId', 'NO-ID');
    const otherParam = navigation.getParam('otherParam', 'some default value');

    return (
      <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
        <Text>Details Screen</Text>
        <Text>itemId: {JSON.stringify(itemId)}</Text>
        <Text>otherParam: {JSON.stringify(otherParam)}</Text>
        <Button
          title="Go to Details... again"
          onPress={() =>
            this.props.navigation.push('Details', {
              itemId: Math.floor(Math.random() * 100),
            })}
        />
        <Button
          title="Go to Home"
          onPress={() => this.props.navigation.navigate('Home')}
        />
        <Button
          title="Go back"
          onPress={() => this.props.navigation.goBack()}
        />
      </View>
    );
  }
}

this.props.navigation.getParam대신에 this.props.navigation.state.params를 이용하여 넘겨진 매개변수에 접근할 수도 있습니다. 이때 매개변수에 아무것도 넘겨지지 않았을 때는 undefined가 나올 수 있다는 것을 알아야합니다. 그러므로 이러한 경우를 피하기 위해서 getParam를 사용하는 것이 쉬울 것입니다.

사용전:

const { name } = this.props.navigation.state.params;

params가 undefined이면 실패합니다.

사용후:

const name = this.props.navigation.getParam('name', 'Peter');

name 또는 매개변수가 undefined라도 name에 기본값 Peter가 설정됩니다.

this.props.navigation.getParam를 사용하지 않고 props를 이용해서 직접 매개변수에 접근하고 싶으면(예를 들어, this.props.itemId) 커뮤니티에서 개발한 react-navigation-props-mapper 패키지를 고려할 수도 있습니다.

참조 사이트

1

스택오버플로우에서 설명하는 자식 네비게이션 https://stackoverflow.com/questions/46269595/react-navigation-navigating-from-child-component

2

리액트네이티브에서 설명하는 자식 네비게이션 https://reactnavigation.org/docs/en/connecting-navigation-prop.html

3

매개변수 넘기기 https://reactnavigation.org/docs/en/params.html

React-Native

Navigation

Contents:

  • 기본
  • 개발 환경 설정
  • 위치 추적
  • 디버깅
  • 컴포넌트
  • 자주 사용하는 컴포넌트
  • Navigations
    • 스크린 이동
    • 자식 컴포넌트에서 스크린 이동
    • 라우트에 매개변수 넘기기
  • 스타일
  • 상태 관리
  • 데이터 가져오기
  • 네트워크
  • 참고 자료
  • 버그 및 디버그

Related Topics

  • Documentation overview
    • Previous: 자주 사용하는 컴포넌트
    • Next: 스타일

Quick search

©2018, Daeki Yoon. | Powered by Sphinx 3.5.2 & Alabaster 0.7.12 | Page source