React Navigation
Stack Navigator
スタック形式の画面遷移定義
React Navigationでは以下のように使用する画面の定義を行います。
- createStackNavigator関数を呼び出しNavigatorオブジェクトを作成する
- 作成したNavigatorオブジェクトを使って、アプリの画面を定義する。下記のコード例のように使用する画面の定義はReact要素として記述します。
- 全体をNavigationContainerコンポーネントで囲む。
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
// React Navigationで表示するそれぞれの画面定義
class HomeScreen extends React.Component {
// 省略
}
class DetailScreen extends React.Component {
// 省略
}
// Navigatorオブジェクトを作成する
const Stack = createStackNavigator();
export default function App() {
return (
// 全体をNavigationContainerで囲む
<NavigationContainer>
{/* StackオブジェクトのNavigatorプロパティ(コンポーネント)でScreenを囲む */}
<Stack.Navigator>
{/*
StackオブジェクトのScreenプロパティ(コンポーネント)で各画面を定義する
nameは画面の識別子で、componentは使用する画面(Reactコンポーネント)
*/}
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Detail" component={DetailScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
画面上部に表示するヘッダは自由にカスタマイズすることができます。カスタマイズ方法は次の二通りの方法があります。
- 画面定義時にoptionsプロパティで指定する。
ヘッダの表示を固定的に行う場合はこちらを使用します。 - navigationオブジェクトのsetOptionsメソッドを使用する。
遷移先の画面で渡されたパラメータに応じてヘッダの表示を変えるという場合はこちらを使用します。
optionsプロパティで指定する場合は以下のようになります。
<Stack.Screen name="Home" component={HomeScreen}
options={{title: 'ホーム'}}
/>
setOptionsメソッドを使う場合は以下のようになります。なお、ここで指定したオプションはoptionsプロパティで指定したオプションにマージされます(optionsプロパティでの指定とsetOptionsメソッドでの指定両方がヘッダの表示に反映されます)
componentDidMount() {
const { navigation, route } = this.props;
const { id } = route.params;
navigation.setOptions({title: `ID ${id}の詳細`}
}
optionsプロパティを使う場合、setOptionsメソッドを使う場合どちらでも設定できるオプションは同じです。代表的なオプションを説明します。すべてのオプションについては以下のURLを参照してください。
https://reactnavigation.org/docs/stack-navigator#options
- title
ヘッダのタイトル(表示文字列) - headerStyle
ヘッダが描画されるViewのスタイル(表示文字列のスタイルは以下2つで指定する) - headerTintColor
ヘッダ文字列と「戻る」ボタンの色 - headerTitleStyle
ヘッダ文字列のスタイル(Textコンポーネントで指定できるもの)
複数の画面で共通の設定を使う(例えば、ヘッダの背景色を共通にする)という場合はScreenではなくNavigatorのscreenOptionsプロパティを使用することもできます。
<NavigationContainer>
<Stack.Navigator screenOptions={{
headerStyle: {
backgroundColor: '#ddd'
}
}}
>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Detail" component={DetailScreen} />
</Stack.Navigator>
<StatusBar style="auto" />
</NavigationContainer>
表示元の画面に戻ってきた際の処理(イベントハンドリング)
画面が初めに表示されるとcomponentDidMountメソッドが呼び出されます。しかし、遷移先の画面から戻ってきてもcomponentDidMountメソッドが呼び出されません。以下のURLで説明されていますが、Stack Navigatorでは別の画面を表示している際も表示元の画面はマウントされたままとなります。
https://reactnavigation.org/docs/navigation-lifecycle
遷移先の画面から戻ってきた際に表示を更新するためにはfocusイベントに対してイベントハンドラを設定し、そのイベントハンドラ内で処理を行う必要があります。focusイベントのイベントハンドラはcomponentDidMountメソッドで設定します。なお、focusイベントのイベントハンドラは若干遅れて実行されるため、componentDidMountメソッドでも同じように処理を記述する必要があることもあります。
componentDidMount() {
// ユーザー名をヘッダに設定
const { navigation, userInfo } = this.props;
navigation.setOptions({ title: userInfo.nickname });
// 遷移先の画面から戻ってきてもcomponentDidMountは呼ばれない
// 別途focusイベントに対してイベントハンドラを設定する
navigation.addListener('focus',
() => {
const { userInfo } = this.props;
// nicknameを最新のものに更新
navigation.setOptions({ title: userInfo.nickname });
}
);
}