I'm using ReactNavigation and am wondering how I can tell when a view will appear (so that I can trigger a data refresh). I see this example using a different navigator NavigatorIOS - Is there a viewDidAppear or viewWillAppear equivalent? but not sure how it would work with https://reactnavigation.org/.
I see the console.log on the navigation dispatches - but is there some event handler that I can hook into on the screen/component level to know if that component/screen is in the foreground? Should I hook into the getStateForAction
method somehow? https://reactnavigation.org/docs/routers/api . I don't want to really create custom route handlers per se, just to detect if the view is entering foreground/will appear, and I'm guessing I can use the navigation event to do that somehow.
Re-rendering screen with the useIsFocused hook React Navigation provides a hook that returns a boolean indicating whether the screen is focused or not. The hook will return true when the screen is focused and false when our component is no longer focused.
While React Navigation 5 was complete overhaul to the API of React Navigation, React Navigation 6 keeps the same API, with some breaking changes to make things more consistent and provide more flexibility.
navigation.addListener Inside a screen, you can add listeners on the navigation prop with the addListener method. The addListener method takes 2 arguments: type of the event, and a callback to be called on the event. It returns a function that can be called to unsubscribe from the event.
So I got this working by creating a redux action and store that tracks the active screen and attaching it to the root navigation onNavigtionChange
event.
<RootNavigation
ref={nav => { this.navigator = nav; }}
onNavigationStateChange={(prevState, currentState) => {
const currentScreen = this.getCurrentRouteName(currentState);
const prevScreen = this.getCurrentRouteName(prevState);
if (prevScreen !== currentScreen) {
this.props.broadcastActiveScreen(currentScreen);
{/*console.log('onNavigationStateChange', currentScreen);*/}
}
}}
/>
actions
import { createAction } from 'redux-actions';
import type { Dispatch } from '../state/store';
export const SCREEN_WILL_APPEAR = 'SCREEN_WILL_APPEAR';
const createScreenWillAppearAction = createAction(SCREEN_WILL_APPEAR);
export const broadcastActiveScreen = (activeScreen: string) => (
(dispatch: Dispatch) => {
dispatch(createScreenWillAppearAction(activeScreen));
}
);
Reducer
export default handleActions({
[SCREEN_WILL_APPEAR]: (state, action) => {
return Object.assign({}, state, {
activeScreen: action.payload,
});
},
}, initialState);
In the screen component
componentWillReceiveProps(nextProps) {
if (nextProps.activeScreen === 'MyScreenName' && nextProps.activeScreen !== this.props.activeScreen) {
// put your on view will appear code here
}
}
I think the didFocus
, willFocus
, didBlur
and willBlur
events will fit your needs.
You need to set/unset them in the componentWillMount
and componentWillUnmount
methods.
See the docs here or here. The examples are not the best though. Feel free to ask if you want an example!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With