Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to tell when a view will appear with ReactNavigation

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.

like image 452
MonkeyBonkey Avatar asked Apr 14 '17 21:04

MonkeyBonkey


People also ask

How do I check my screen focus or not in react navigation?

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.

Should I use react navigation 5 or 6?

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.

How do I use navigation addListener?

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.


Video Answer


2 Answers

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
    }
   }
like image 171
MonkeyBonkey Avatar answered Jan 01 '23 09:01

MonkeyBonkey


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!

like image 27
Pierre Poupin Avatar answered Jan 01 '23 09:01

Pierre Poupin