Rect Nativeでルートを管理するのによくReact Navigationを使うのですが、普通にReact Navigationをインストールすると 画面コンポーネントにバインドされたnavigationインスタンスを使って遷移を行う感じになると思うのですが、 APIの成功・不成功をもとに画面を遷移させたりなどなど画面以外の場所でnavigationさせたい時ってありますよね。
今回はそんな時用のTipsです。参考はこちらです。
Navigating without the navigation prop
さっそくやってみる
全体の仕組みとしては、topレベルのコンポーネントがnavigateインスタンスへの参照を持っているのでその参照を適当なモジュールに保持して適宜それを呼び出して使うという形です。 navigation
具体的なコードとしては、以下のような形でrefsを使ってnavigationへの参照が渡せるので、
import { createStackNavigator, createAppContainer } from 'react-navigation';
import NavigationService from './NavigationService';
const TopLevelNavigator = createStackNavigator({ /* ... */ })
const AppContainer = createAppContainer(TopLevelNavigator);
export default class App extends React.Component {
render() {
return (
<AppContainer
ref={navigatorRef => {
NavigationService.setTopLevelNavigator(navigatorRef);
}}
/>
);
}
}
NavigationServiceというその参照を保持するモジュールを用意してAppContainerでその参照をセットするという形です。
実際には、以下のようなモジュールを用意します。
// NavigationService.js
import { NavigationActions } from 'react-navigation';
let _navigator;
function setTopLevelNavigator(navigatorRef) {
_navigator = navigatorRef;
}
function navigate(routeName, params) {
_navigator.dispatch(
NavigationActions.navigate({
routeName,
params,
})
);
}
export default {
navigate,
setTopLevelNavigator,
};
コードをみてわかるようにsetTopLevelNavigatorでnavigateへの参照を保存して、
navigateさせたい時は、NavigationService.navigate(routeName, params)
で画面遷移させることができる。
という具合です。
下は、サインインが成功したらマイページに遷移させるというコードの例ですね。
import NavigationService from './NavigationService'
export const signInAsyncFunciton = async ({ email, password }) => (dispatch) => {
const acitons = { signIn, signInSuccess, signInError } = actions
try {
dispatch(signIn())
const { data } = await api.fetchHoge({ email, password })
if (data) {
// SignIn Success
dispatch(signInSuccess(data))
NavigationService.navigate('Mypage')
}
} catch (error) {
dispatch(signInError(error))
}
}
※コードはイメージです。
まとめ
というわけで、navigationをprops経由しないで行う方法でした。
これを使うと好きなところで画面を操作できるので、自由といえば自由なのですが、あまり乱用するとどこで、 画面を操作してわからなくなるので乱用は禁物ですね。ただログイン後遷移させたい時やリソースを削除した後に、詳細画面から一覧画面に遷移させたい。 などあると思うので使いどころ見極めてできると良いとですね。
では。