[Navigator]: Allow developer to observe the focus change events from the owner or the children

of the navigator component.

Summary:
Per offline discussion with @evv, we'd like to deprecate the `onDidFocus` and `onWillFocus`
API that makes it really hard for the descendent children of a navigator to observe its focus
change events.
@public

Since for now the descendent children do have access to the navigator via `this.props.navigator`,
this diff makes it easy to observe the focus change event by doing:

```
this.props.navigator.addListener('willfocus', this._onFocus);
```

The goal is to make the event system in navigator more useful and maintainable.

Test Plan:
Test Video: https://www.facebook.com/pxlcld/mrzS
1. jest:  ./Libraries/FBReactKit/js/runTests.js NavigationEventEmitter
2. Load UI Explorer: <Navigator />, see console logs that shows the focus change events fires.
This commit is contained in:
Hedger Wang
2015-06-16 09:08:16 -07:00
parent 5793f5c4c4
commit 0a875790f5
7 changed files with 322 additions and 2 deletions

View File

@@ -30,11 +30,11 @@
var AnimationsDebugModule = require('NativeModules').AnimationsDebugModule;
var Dimensions = require('Dimensions');
var InteractionMixin = require('InteractionMixin');
var NavigationContext = require('NavigationContext');
var NavigatorBreadcrumbNavigationBar = require('NavigatorBreadcrumbNavigationBar');
var NavigatorNavigationBar = require('NavigatorNavigationBar');
var NavigatorSceneConfigs = require('NavigatorSceneConfigs');
var PanResponder = require('PanResponder');
var Platform = require('Platform');
var React = require('React');
var StaticContainer = require('StaticContainer.react');
var StyleSheet = require('StyleSheet');
@@ -203,11 +203,17 @@ var Navigator = React.createClass({
initialRouteStack: PropTypes.arrayOf(PropTypes.object),
/**
* @deprecated
* Use `navigationContext.addListener('willfocus', callback)` instead.
*
* Will emit the target route upon mounting and before each nav transition
*/
onWillFocus: PropTypes.func,
/**
* @deprecated
* Use `navigationContext.addListener('didfocus', callback)` instead.
*
* Will be called with the new route of each scene after the transition is
* complete or after the initial mounting
*/
@@ -321,7 +327,10 @@ var Navigator = React.createClass({
},
componentWillUnmount: function() {
if (this._navigationContext) {
this._navigationContext.dispose();
this._navigationContext = null;
}
},
/**
@@ -461,12 +470,16 @@ var Navigator = React.createClass({
},
_emitDidFocus: function(route) {
this.navigationContext.emit('didfocus', {route: route});
if (this.props.onDidFocus) {
this.props.onDidFocus(route);
}
},
_emitWillFocus: function(route) {
this.navigationContext.emit('willfocus', {route: route});
var navBar = this._navBar;
if (navBar && navBar.handleWillFocus) {
navBar.handleWillFocus(route);
@@ -1139,6 +1152,14 @@ var Navigator = React.createClass({
</View>
);
},
// Getter for `navigationContext`.
get navigationContext() {
if (!this._navigationContext) {
this._navigationContext = new NavigationContext();
}
return this._navigationContext;
}
});
module.exports = Navigator;