Perviously when I wanted to make some actions when screen is opened I put them inside componentDidMount. For example I can fetch some data.
like this.
componentDidMount() {
this.updateData();
}
But with react-navigation componentDidMount occurs only one time when user open screen first time, and if later user open this page again it will not trigger componentDidMount.
What is proper way to detect when page(screen) is activated and do actions?
With react-navigation
, you can do that.
Add listeners in componentDidMount
or componentWillMount
this.subs = [
this.props.navigation.addListener('didFocus', (payload) => this.componentDidFocus(payload)),
];
or
this.subs = [
this.props.navigation.addListener('didFocus', this.componentDidFocus),
this.props.navigation.addListener('willBlur', this.componentWillBlur),
];
Then you can do anything in componentDidFocus
, like fetching data, updating data,...
In componentWillUnmount
, remove listeners
componentWillUnmount() {
this.subs.forEach(sub => sub.remove());
}
For more detail, see this PR: https://github.com/react-navigation/react-navigation/pull/3345
Updated:
addListener
- Subscribe to updates to navigation lifecycle
React Navigation emits events to screen components that subscribe to
them:
willBlur
- the screen will be unfocused
willFocus
- the screen will focus
didFocus
- the screen focused (if there was a transition, the
transition completed)
didBlur
- the screen unfocused (if there was a transition, the
transition completed)
Ref: https://reactnavigation.org/docs/en/navigation-prop.html#addlistener-subscribe-to-updates-to-navigation-lifecycle
Updated example:
const didBlurSubscription = this.props.navigation.addListener(
'didBlur',
payload => {
console.debug('didBlur', payload);
}
);
JSON payload:
{
action: { type: 'Navigation/COMPLETE_TRANSITION', key: 'StackRouterRoot' },
context: 'id-1518521010538-2:Navigation/COMPLETE_TRANSITION_Root',
lastState: undefined,
state: undefined,
type: 'didBlur',
};
componentDidMount
/ componentWillUnmount
does not work in all cases of navigation (like tabs).
You need to use addListener
with events didFocus and didBlur to make such actions. See documentation for details
Perhaps try componentDidUpdate and set a state within your component. When the state changes the re-render occurs