티스토리 뷰

 react-navigation 에서는 타이틀 영역을 Header라고 부른다. 

 

이 헤더를 커스터마이징 하는 방법을 한 번 알아보자.

 

직전 포스팅의 예제를 그대로 사용한다.


1. Props 사용

 

◎ App.js

import React from 'react';
import HomeScreen from './screens/HomeScreen';
import DetailScreen from './screens/DetailScreen';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
import {NavigationContainer} from '@react-navigation/native';

const Stack = createNativeStackNavigator();

const App = () => {
  return (
    <NavigationContainer>
      <Stack.Navigator initialRouteName={'Home'}>
        <Stack.Screen
          name="Home"
          component={HomeScreen}
          options={{
            title: '홈 상단 헤더',
          }}
        />
        <Stack.Screen name="Detail" component={DetailScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
};

export default App;

 

Screen 컴포넌트로 options Props를 보내 title을 설정한다.

 

 

 

2. setOptions 함수 사용

 

◎ HomeScreen.js

import React, {useEffect} from 'react';
import {View, Button} from 'react-native';

const HomeScreen = ({navigation}) => {
  useEffect(() => {
    navigation.setOptions({title: '상단 헤더 홈'});
  }, [navigation]);
  return (
    <View>
      <Button
        title={'Detail 1 열기'}
        onPress={() => navigation.push('Detail', {id: 1})}
      />
      <Button
        title={'Detail 2 열기'}
        onPress={() => navigation.push('Detail', {id: 2})}
      />
      <Button
        title={'Detail 3 열기'}
        onPress={() => navigation.push('Detail', {id: 3})}
      />
    </View>
  );
};

export default HomeScreen;

 

혹은 위와 같이 navigation의 setOptions를 사용하여 설정할 수도 있다.

 

아래와 같이 람다를 활용하여 라우트 파라미터를 직접 전송해 사용해도 된다.

 

◎ App.js

import React from 'react';
import HomeScreen from './screens/HomeScreen';
import DetailScreen from './screens/DetailScreen';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
import {NavigationContainer} from '@react-navigation/native';

const Stack = createNativeStackNavigator();

const App = () => {
  return (
    <NavigationContainer>
      <Stack.Navigator initialRouteName={'Home'}>
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen
          name="Detail"
          component={DetailScreen}
          options={({route}) => ({
            title: `상세 정보 - ${route.params.id}`,
          })}
        />
      </Stack.Navigator>
    </NavigationContainer>
  );
};

export default App;


헤더의 스타일은 아래와 같이 다양한 옵션들을 사용하여 변경이 가능하다.

 

◎ App.js

import React from 'react';
import HomeScreen from './screens/HomeScreen';
import DetailScreen from './screens/DetailScreen';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
import {NavigationContainer} from '@react-navigation/native';

const Stack = createNativeStackNavigator();

const App = () => {
  return (
    <NavigationContainer>
      <Stack.Navigator initialRouteName={'Home'}>
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen
          name="Detail"
          component={DetailScreen}
          options={({route}) => ({
            title: `상세 정보 - ${route.params.id}`,
            headerStyle: {
              backgroundColor: '#29b6f6',
            },
            headerTintColor: '#ffffff',
            headerTitleStyle: {
              fontSize: 20,
              fontWeight: 'bold',
            },
          })}
        />
      </Stack.Navigator>
    </NavigationContainer>
  );
};

export default App;


헤더의 좌측, 타이틀, 우측 영역에 원래 UI가 아닌 다른 컴포넌트를 삽입하여 보여줄 수도 있다.

 

◎ App.js

import React from 'react';
import HomeScreen from './screens/HomeScreen';
import DetailScreen from './screens/DetailScreen';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
import {NavigationContainer} from '@react-navigation/native';
import {Text, TouchableOpacity, View} from 'react-native';

const Stack = createNativeStackNavigator();

const App = () => {
  return (
    <NavigationContainer>
      <Stack.Navigator initialRouteName={'Home'}>
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen
          name="Detail"
          component={DetailScreen}
          options={{
            headerLeft: ({onPress}) => (
              <TouchableOpacity onPress={onPress}>
                <Text>Left</Text>
              </TouchableOpacity>
            ),
            headerTitle: ({children}) => (
              <View>
                <Text>{children}</Text>
              </View>
            ),
            headerRight: () => (
              <View>
                <Text>Right</Text>
              </View>
            ),
            /* 뒤로가기 화살표 제거 */
            headerBackVisible: false,
          }}
        />
      </Stack.Navigator>
    </NavigationContainer>
  );
};

export default App;


혹은 headerShown 옵션을 false로 하여 헤더를 숨길 수도 있다.

 

◎ App.js

import React from 'react';
import HomeScreen from './screens/HomeScreen';
import DetailScreen from './screens/DetailScreen';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
import {NavigationContainer} from '@react-navigation/native';
import {Text, TouchableOpacity, View} from 'react-native';

const Stack = createNativeStackNavigator();

const App = () => {
  return (
    <NavigationContainer>
      <Stack.Navigator initialRouteName={'Home'}>
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen
          name="Detail"
          component={DetailScreen}
          options={{
            headerShown: false,
          }}
        />
      </Stack.Navigator>
    </NavigationContainer>
  );
};

export default App;

 

이 때, 주의할 점은 아이폰은 headerShown을 false로 놓을 시, StatusBack영역을 침범하여 화면이 나타날 수도 있다.

 

이럴 때는 SafeAreaView 컴포넌트로 해당 View를 감싸줘야 한다.

import React from 'react';
import { View, Text, StyleSheet, Button } from "react-native";

const DetailScreen = ({route, navigation}) => {
  return (
    <SafeAreaView>
    	<View style={styles.block}>
     	 ...
    	</View>
    </SafeAreaView>
  );
};

export default DetailScreen;

Comments