J'aimerais actualiser les données à l'écran dans une application native native à chaque fois que l'écran apparaît - comme dans une méthode ViewWillAppear
. J'ai essayé d'utiliser la méthode componentWillMount
, mais il semble qu'elle se déclenche une fois avant son affichage et ne se déclenche pas à nouveau lorsque vous revenez à la vue.
En regardant cet exemple https://reactnavigation.org/docs/guides/screen-tracking , il semble que je puisse ajouter un écouteur à la méthode onNavigationStateChange
dans la navigation racine, mais j'aimerais conserver la logique. à l'écran car cela devient confus si je déplace la logique d'extraction de données pour cet ébauche vers le navigateur racine.
J'ai essayé de suivre l'exemple et de définir cette méthode sur stacknavigation mais cela ne semble pas se déclencher.
<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);
}
}}
/>
Alors voici comment je l’ai fait avec la variable 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);*/}
}
}}
/>
Et sur votre écran, vous pouvez vérifier si votre vue apparaîtra, notez que MyPage
est le nom de l'itinéraire de votre objet de navigation.
componentWillReceiveProps(nextProps) {
if ((nextProps.activeScreen === 'MyPage' && nextProps.activeScreen !== this.props.activeScreen)) {
// do your on view will appear logic here
}
}
Voici mon réducteur de navigateur.
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;
}
Et ensuite, nous devons connecter le module/la route au magasin Redux (sceneIsActive est le bit important):
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);
Ensuite, dans votre composant, vous pouvez surveiller le code/trigger lorsque la scène devient active:
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();
}
}
Sachez que componentWillReceiveProps
ne s'exécute pas lors du montage initial. Alors, n'oubliez pas d'appeler votre doSomethingWhenScreenBecomesActive
également.