我如何判断屏幕是否已通过 React Navigation 导航到
How can I tell if the screen is navigated to with ReactNavigation
我想在屏幕出现时在 React Native 应用程序中刷新屏幕上的数据 - 就像在 ViewWillAppear
方法中一样。我尝试使用 componentWillMount
方法,但看起来它在出现之前会触发一次,并且在再次导航到视图时不会再次触发。
查看此示例 https://reactnavigation.org/docs/guides/screen-tracking,我似乎可以在根导航的 onNavigationStateChange
方法上添加一个侦听器,但我想将逻辑保留在屏幕中如果我将那个屏幕的数据获取逻辑移到根导航器之外,就会感到困惑。
我已尝试按照示例并将该方法设置为我的 stacknavigation,但它似乎没有触发。
<RootNavigation ref={nav => { this.navigator = nav; }}
onNavigationStateChange={(prevState, currentState, action) => {
// maybe here I can fire redux event or something to let screens
// know that they are getting focus - however it doesn't fire so
// I might be implementing this incorrectly
const currentScreen = getCurrentRouteName(currentState);
const prevScreen = getCurrentRouteName(prevState);
if (prevScreen !== currentScreen) {
console.log('navigating to this screen', currentScreen);
}
}}
/>
这是我的 navigator reducer。
function getCurrentRouteName(navState) {
if (!navState) {
return null;
}
const navigationState = (navState && navState.toJS && navState.toJS()) || navState;
const route = navigationState.routes[navigationState.index];
// dive into nested navigators
if (route.routes) {
return getCurrentRouteName(route);
}
return route.routeName;
}
export default function NavigatorReducer(state, action) {
// Initial state
if (!state) {
return fromJS(AppNavigator.router.getStateForAction(action, state));
}
// Is this a navigation action that we should act upon?
if (includes(NavigationActions, action.type)) {
// lets find currentScreen before this action based on state
const currentScreen = getCurrentRouteName(state);
const nextState = AppNavigator.router.getStateForAction(action, state.toJS());
// determine what the new screen will be after this action was performed
const nextScreen = getCurrentRouteName(nextState);
if (nextScreen !== currentScreen) {
nextState.currentRoute = nextScreen;
console.log(`screen changed, punk: ${currentScreen} -> ${nextScreen}`);
}
return fromJS(nextState);
}
return state;
}
然后我们必须将 module/route 连接到 redux 存储(sceneIsActive 是重要的一点):
export default connect(
state => ({
counter: state.getIn(['counter', 'value']),
loading: state.getIn(['counter', 'loading']),
sceneIsActive: state.getIn(['navigatorState', 'currentRoute']) === 'Counter',
}),
dispatch => {
return {
navigate: bindActionCreators(NavigationActions.navigate, dispatch),
counterStateActions: bindActionCreators(CounterStateActions, dispatch),
};
},
)(CounterView);
然后在您的组件中,您可以在场景激活时查看 for/trigger 代码:
componentWillReceiveProps(nextProps) {
if (nextProps.sceneIsActive && (this.props.sceneIsActive !== nextProps.sceneIsActive)) {
console.log('counter view is now active, do something about it', this.props.sceneIsActive, nextProps.sceneIsActive);
doSomethingWhenScreenBecomesActive();
}
}
知道 componentWillReceiveProps
在初始安装时不会 运行。所以别忘了给你的 doSomethingWhenScreenBecomesActive
打电话。
下面是我如何使用 onNavigateStateChange
.
<RootNavigation
ref={nav => { this.navigator = nav; }}
uriPrefix={prefix}
onNavigationStateChange={(prevState, currentState) => {
const currentScreen = this.getCurrentRouteName(currentState);
const prevScreen = this.getCurrentRouteName(prevState);
if (prevScreen !== currentScreen) {
this.props.emitActiveScreen(currentScreen);
{/*console.log('onNavigationStateChange', currentScreen);*/}
}
}}
/>
并且在您的屏幕中,您可以检查您的视图是否会出现,请注意 MyPage
是导航对象中的路线名称。
componentWillReceiveProps(nextProps) {
if ((nextProps.activeScreen === 'MyPage' && nextProps.activeScreen !== this.props.activeScreen)) {
// do your on view will appear logic here
}
}
我想在屏幕出现时在 React Native 应用程序中刷新屏幕上的数据 - 就像在 ViewWillAppear
方法中一样。我尝试使用 componentWillMount
方法,但看起来它在出现之前会触发一次,并且在再次导航到视图时不会再次触发。
查看此示例 https://reactnavigation.org/docs/guides/screen-tracking,我似乎可以在根导航的 onNavigationStateChange
方法上添加一个侦听器,但我想将逻辑保留在屏幕中如果我将那个屏幕的数据获取逻辑移到根导航器之外,就会感到困惑。
我已尝试按照示例并将该方法设置为我的 stacknavigation,但它似乎没有触发。
<RootNavigation ref={nav => { this.navigator = nav; }}
onNavigationStateChange={(prevState, currentState, action) => {
// maybe here I can fire redux event or something to let screens
// know that they are getting focus - however it doesn't fire so
// I might be implementing this incorrectly
const currentScreen = getCurrentRouteName(currentState);
const prevScreen = getCurrentRouteName(prevState);
if (prevScreen !== currentScreen) {
console.log('navigating to this screen', currentScreen);
}
}}
/>
这是我的 navigator reducer。
function getCurrentRouteName(navState) {
if (!navState) {
return null;
}
const navigationState = (navState && navState.toJS && navState.toJS()) || navState;
const route = navigationState.routes[navigationState.index];
// dive into nested navigators
if (route.routes) {
return getCurrentRouteName(route);
}
return route.routeName;
}
export default function NavigatorReducer(state, action) {
// Initial state
if (!state) {
return fromJS(AppNavigator.router.getStateForAction(action, state));
}
// Is this a navigation action that we should act upon?
if (includes(NavigationActions, action.type)) {
// lets find currentScreen before this action based on state
const currentScreen = getCurrentRouteName(state);
const nextState = AppNavigator.router.getStateForAction(action, state.toJS());
// determine what the new screen will be after this action was performed
const nextScreen = getCurrentRouteName(nextState);
if (nextScreen !== currentScreen) {
nextState.currentRoute = nextScreen;
console.log(`screen changed, punk: ${currentScreen} -> ${nextScreen}`);
}
return fromJS(nextState);
}
return state;
}
然后我们必须将 module/route 连接到 redux 存储(sceneIsActive 是重要的一点):
export default connect(
state => ({
counter: state.getIn(['counter', 'value']),
loading: state.getIn(['counter', 'loading']),
sceneIsActive: state.getIn(['navigatorState', 'currentRoute']) === 'Counter',
}),
dispatch => {
return {
navigate: bindActionCreators(NavigationActions.navigate, dispatch),
counterStateActions: bindActionCreators(CounterStateActions, dispatch),
};
},
)(CounterView);
然后在您的组件中,您可以在场景激活时查看 for/trigger 代码:
componentWillReceiveProps(nextProps) {
if (nextProps.sceneIsActive && (this.props.sceneIsActive !== nextProps.sceneIsActive)) {
console.log('counter view is now active, do something about it', this.props.sceneIsActive, nextProps.sceneIsActive);
doSomethingWhenScreenBecomesActive();
}
}
知道 componentWillReceiveProps
在初始安装时不会 运行。所以别忘了给你的 doSomethingWhenScreenBecomesActive
打电话。
下面是我如何使用 onNavigateStateChange
.
<RootNavigation
ref={nav => { this.navigator = nav; }}
uriPrefix={prefix}
onNavigationStateChange={(prevState, currentState) => {
const currentScreen = this.getCurrentRouteName(currentState);
const prevScreen = this.getCurrentRouteName(prevState);
if (prevScreen !== currentScreen) {
this.props.emitActiveScreen(currentScreen);
{/*console.log('onNavigationStateChange', currentScreen);*/}
}
}}
/>
并且在您的屏幕中,您可以检查您的视图是否会出现,请注意 MyPage
是导航对象中的路线名称。
componentWillReceiveProps(nextProps) {
if ((nextProps.activeScreen === 'MyPage' && nextProps.activeScreen !== this.props.activeScreen)) {
// do your on view will appear logic here
}
}