React navigation v2 is a library for handling navigation in React Native . When you are using Tab / Screen, maybe you only want to render it when it is been displayed. Otherwise, something like re-rendering multiple lists in multiple tabs. That’s a disaster… Let’s see how to do that.

If you come from the web. Just like in react-router , in react navigation, the navigation prop will be changed to cause re-render. And when you are like me, use one same list component for multiple tabs, you will have problems when trying to figure out how to not-render and re-render at the proper time. But that is something we will solve today.

1. How to know that a tab is been entered or exited

React navigation provides a this.props.navigation.addListener method where you can subscribe the events.

you can use it like this

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

componentDidMount() {

const { addListener } = this .props.navigation

const { isDisplayed } = this .state

const self = this



this .listeners = [

addListener( 'didFocus' , () => {

if (self.state.isDisplayed !== true ) {

self.setState({ isDisplayed : true })

}

}),

addListener( 'willBlur' , () => {

if (self.state.isDisplayed !== false ) {

self.setState({ isDisplayed : false })

}

}),

]

}



And unsubscribe like this:

1

2

3

4

5

componentWillUnmount() {

this .listeners.forEach(

sub => { sub.remove() },

)

}



You can add the listeners to an array when componentDidMount

unsubscribe them when componentWillUnmount

Then you can use this.state.isDisplayed to check the status

One crucial thing to remember, when you subscribe using that arrow function addListener('didFocus', () => {}) , the context inside that lambda is not your current component, so you need to refer to an outside variable like I use self.blahBlah rather than refer to this.blahBlah directly, because that is not the same. The this you will get in that lambda is the global object.

2. You can use 4 events

According to the official doc:

willBlur - the screen will be unfocused

- the screen will be unfocused willFocus - the screen will focus

- the screen will focus didFocus - the screen focused (if there was a transition, the transition completed)

- the screen focused (if there was a transition, the transition completed) didBlur - the screen unfocused (if there was a transition, the transition completed)

Two cases here:

The screen is about to displayed (from false to true ) The screen is been displayed ( true ) but props has been changed (which means its content is updating, the component should re-render)

1

2

3

4

5

6

7

8

9

10

11

12

shouldComponentUpdate(

nextProps,

nextState,

) {

const { isDisplayed } = this .state

const { dataForRender } = this .props



return (

(!isDisplayed && nextState.isDisplayed) ||

(isDisplayed && dataForRender !== nextProps.dataForRender)

)

}



You might think why not just nextState.isDisplayed === true . Well, not only it will not cause re-rendering when the screen has been displayed but props has been changed. But also it will cause the tab that is been exited to re-render. Which means, when exit tab2 to tab1 , both tab1 and tab2 will be re-rendered which is not what we want.

4. End

Anyway, you get it. Hope it helps.

Thanks for reading!

Follow me (albertgao) on twitter, if you want to hear more about my interesting ideas.