I noticed that whenever I navigate to another page using the navigate props available to my ponent, it triggers a re-render of the ponent and ponentDidMount is being called whenever I navigate to a screen that has rendered before.
For instance, when I navigate a user to their profile page and they decided to go back to the dashboard, the dashboard ponent which has been initially rendered is being rendered again and ponentDidMount is being called thereby slowing down the application.
import { StackNavigator } from 'react-navigation';
const Routes = StackNavigator({
home: {
screen: HomeScreen
},
dashboard: {
screen: Dashboard
},
profile: {
screen: Profile
}
},
{
headerMode: 'none',
});
In my ponent I navigate the user with this.props.navigation.navigate('ScreenName')
I would appreciate any help to stop the ponent from re-rendering when navigating back to it. Thanks
I noticed that whenever I navigate to another page using the navigate props available to my ponent, it triggers a re-render of the ponent and ponentDidMount is being called whenever I navigate to a screen that has rendered before.
For instance, when I navigate a user to their profile page and they decided to go back to the dashboard, the dashboard ponent which has been initially rendered is being rendered again and ponentDidMount is being called thereby slowing down the application.
import { StackNavigator } from 'react-navigation';
const Routes = StackNavigator({
home: {
screen: HomeScreen
},
dashboard: {
screen: Dashboard
},
profile: {
screen: Profile
}
},
{
headerMode: 'none',
});
In my ponent I navigate the user with this.props.navigation.navigate('ScreenName')
I would appreciate any help to stop the ponent from re-rendering when navigating back to it. Thanks
Share Improve this question asked Apr 16, 2018 at 13:20 dealwapdealwap 7213 gold badges17 silver badges38 bronze badges 2-
1
Assuming that your screens are Stateful, add a
shouldComponentUpdate
lifecycle method that returnsfalse
if you do not want a re-render. – Dan Commented Apr 16, 2018 at 15:30 - 1 Thanks for your response. How about on initial render, I would like the ponent to be normally rendered only when the user is navigating back to it after the first instance. – dealwap Commented Apr 16, 2018 at 15:38
4 Answers
Reset to default 2I would have a state variable in your constructor that keeps track if you navigated. State is only relevant to the current ponent. So if you navigate to 'ScreenName' multiple times, the stack builds and each ScreenName ponent has its own state.
constructor(props)
super(props)
this.state = {
navigatedAway : false
}
Then before you navigate to your 'ScreenName' screen update the state
this.setState({
navigatedAway : true
},
() => {
this.props.navigation.navigate('ScreenName');
}
);
Use syntax above to make sure state isUpdated THEN navigate. Then like Dan said in ments above if your function shouldComponentUdate have a condition statement.
shouldComponentUpdate(newProps){
// return true if you want to update
// return false if you do not
}
* Side Note *
When you navigate I don't believe the ponent is unmounted. You could verify this by simply printing to console. Correct me if I am wrong though, I am fairly new to react native.
ponentDidMount() {
console.log("COMPONENT_CONTENT_MOUNTED")
}
ponentWillUnmount({
console.log("COMPONENT_CONTENT_UNMOUNTED")
}
If you are using React Navigation 5.X, just do the following:
import { useIsFocused } from '@react-navigation/native'
export default function App(){
const isFocused = useIsFocused()
useEffect(() => {
//Update the state you want to be updated
} , [isFocused])
}
If I understand your question correctly, when you navigate away, the ponent is unmounted.
When you navigate back, it must be re-mounted, hence re-rendered.
In general, any UI change necessitates a re-render. No way around that - It's kind of "by definition".
You might be able to cache the page.
Or use the reselect
library to cache expensive to obtain data, so the calculations for re-rendering are quick and minimal.
If react/react-native thinks the props have changed (in an already mounted/rendered ponent), it will also re-render, but you can influence this decision via shouldComponentUpdate()
.
Just add React.memo to your export of ponent that reload each time. So instead of export default ponent
you would have: export default React.memo(ponent);
Which does a parison of props and only re-renders if props change (so not on navigate but on actual changes, which is what you want)