peter-mach / react-navigation-is-focused-hoc

Ready to use solution using HOC to expose props.isFocused for react-navigation. No Redux needed.
MIT License
169 stars 21 forks source link

Render called repeatedly after changing screens via navigate() #1

Closed gititon closed 6 years ago

gititon commented 7 years ago

Hi @pmachowski , thank you for this! I'm finding render() is called repeatedly when changing screens a few times via navigate(). I confirmed that this does not happen when I don't use react-navigation-is-focused-hoc.

I put together a very simple application using your example (with the addition of another screen to navigate to), a Button on each screen that invokes navigate(), and console logging in each screen's render() method that illustrates this behavior. If you run the app and hit the "Continue" Button a few times to navigate() back and forth between screens, you'll observe in the console debug log that render() is called many times per Button press/invocation of navigate().

I would be very grateful if you could tell me how to modify either your module or my own code to prevent this behavior from happening and ensure that render() is only called on the screen/Component that navigate() switches to.

The code for the example application that exhibits this behavior is below. Thank you very much for your help!

index.android.js

import './src/App';

src/App.js

import React from 'react'
import { AppRegistry } from 'react-native'
import { StackNavigator } from 'react-navigation'
import { updateFocus } from 'react-navigation-is-focused-hoc'

import MyScreenView from './screens/myScreenView'
import MyOtherView from './screens/myOtherView'

// navigation
const AppNavigator = StackNavigator({
  MyScreenView: { screen: MyScreenView },
  MyOtherView: { screen: MyOtherView },
}, {
  initialRouteName: 'MyScreenView',
})

export default class App extends React.Component {

  render() {
    return (
      <AppNavigator
        onNavigationStateChange={(prevState, currentState) => {
          updateFocus(currentState)
        }}
      />
    )
  }
}

AppRegistry.registerComponent('issue', () => App);

src/screens/myScreenView.js

import React from 'react'
import {
  View,
  Text,
  Button
} from 'react-native'
import { withNavigationFocus } from 'react-navigation-is-focused-hoc'

class MyScreenView extends React.Component {

  render() {
      console.log("render() called on MyScreenView");
      const { navigate } = this.props.navigation;
    return (
     <View>
        {this.props.isFocused
          ? <Text>I am focused</Text>
          : <Text>I am not focused</Text>
        }
          <Button
            onPress={() => navigate('MyOtherView')}
            title="Continue"
          />
      </View>
    )
  }
}

// second argument is the route name specified during StackNavigator initialization.
export default withNavigationFocus(MyScreenView, 'MyScreenView')

src/screens/myOtherView.js

import React from 'react'
import {
  View,
  Text,
  Button
} from 'react-native'
import { withNavigationFocus } from 'react-navigation-is-focused-hoc'

class MyOtherView extends React.Component {

  render() {
      console.log("render() called on MyOtherView");
      const { navigate } = this.props.navigation;
    return (
      <View>
        {this.props.isFocused
          ? <Text>I am focused</Text>
          : <Text>I am not focused</Text>
        }
          <Button
            onPress={() => navigate('MyScreenView')}
            title="Continue"
          />
      </View>
    )
  }
}

// second argument is the route name specified during StackNavigator initialization.
export default withNavigationFocus(MyOtherView, 'MyOtherView')
peter-mach commented 6 years ago

That should be fixed in 1.1.0