{"action":"created","issue":{"url":"https://api.github.com/repos/react-navigation/react-navigation/issues/3345","repository_url":"https://api.github.com/repos/react-navigation/react-navigation","labels_url":"https://api.github.com/repos/react-navigation/react-navigation/issues/3345/labels{/name}","comments_url":"https://api.github.com/repos/react-navigation/react-navigation/issues/3345/comments","events_url":"https://api.github.com/repos/react-navigation/react-navigation/issues/3345/events","html_url":"https://github.com/react-navigation/react-navigation/pull/3345","id":291015626,"number":3345,"title":"Navigation Event Subscriptions","user":{"login":"ericvicenti","id":1483597,"avatar_url":"https://avatars1.githubusercontent.com/u/1483597?v=4","gravatar_id":"","url":"https://api.github.com/users/ericvicenti","html_url":"https://github.com/ericvicenti","followers_url":"https://api.github.com/users/ericvicenti/followers","following_url":"https://api.github.com/users/ericvicenti/following{/other_user}","gists_url":"https://api.github.com/users/ericvicenti/gists{/gist_id}","starred_url":"https://api.github.com/users/ericvicenti/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ericvicenti/subscriptions","organizations_url":"https://api.github.com/users/ericvicenti/orgs","repos_url":"https://api.github.com/users/ericvicenti/repos","events_url":"https://api.github.com/users/ericvicenti/events{/privacy}","received_events_url":"https://api.github.com/users/ericvicenti/received_events","type":"User","site_admin":false},"labels":[{"id":598136973,"url":"https://api.github.com/repos/react-navigation/react-navigation/labels/PR:%20needs%20review","name":"PR: needs review","color":"fbca04","default":false}],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":30,"created_at":"2018-01-23T22:24:53Z","updated_at":"2018-02-05T12:29:04Z","closed_at":"2018-01-25T08:13:29Z","author_association":"CONTRIBUTOR","pull_request":{"url":"https://api.github.com/repos/react-navigation/react-navigation/pulls/3345","html_url":"https://github.com/react-navigation/react-navigation/pull/3345","diff_url":"https://github.com/react-navigation/react-navigation/pull/3345.diff","patch_url":"https://github.com/react-navigation/react-navigation/pull/3345.patch"},"body":"Implements the following event subscription system, as proposed in https://github.com/react-navigation/rfcs/pull/1\r\n\r\n\r\n# Summary\r\n\r\nAdd an event emitter to the navigation prop that emits focus/blur events for the route.\r\n\r\nThis proposal has been pioneered by @satya164: https://github.com/react-navigation/react-navigation/issues/1363\r\n\r\nThis will resolve longstanding requests for such functionality, as seen here: https://github.com/react-navigation/react-navigation/issues/51\r\n\r\n# Basic example\r\n\r\nIn this example, we focus the first text input when the screen has completed transitioning:\r\n\r\n```\r\ncomponentDidMount() {\r\n  this._sub = this.props.navigation.addListener(\r\n    'didFocus',\r\n    this._focusFirstTextInput\r\n  );\r\n}\r\ncomponentWillUnmount() {\r\n  this._sub.remove();\r\n}\r\n```\r\n\r\n# Motivation\r\n\r\nScreens need to know about navigation changes while they are mounted. Consider the following use cases:\r\n\r\n### Data and Media subscription\r\n\r\nScreens must know when to request live data or when to enable/disable resource-intensive APIs. Media should be able to auto-pause at correct times.\r\n\r\n### Unmounting\r\n\r\nTabs and cards may need to unmount and re-mount contents when they are focused.\r\n\r\nMay be useful in conjunction with removeClippedSubviews and utilities like https://github.com/SoftwareMansion/react-native-resource-saving-container\r\n\r\n### Keyboard dismissal\r\n\r\nKB must dismiss when scene _starts_ to transition back (mayBlur)\r\n\r\n### StatusBar Re-configuration\r\n\r\nScreens may want to re-configure the status bar when the become active or blurred\r\n\r\n### Input autofocus\r\n\r\nInputs want to open the keyboard after the screen finishes transition\r\n\r\n### Related Concepts for Future work and exploration:\r\n\r\n_Back button handling_ - Screens may want to prevent back actions based on internal state\r\n\r\n_Refocus_ - On extra tab press, navigate to top of stack, then scroll to top on next press\r\n\r\n# Detailed design\r\n\r\n## Event System\r\n\r\nAn event emitter will be provided as part of each screen navigation prop. The events will be emitted by the navigator as changes happen to the navigation state.\r\n\r\n`this.props.navigation.addListener` will be a `NavigationEventSubscriber`:\r\n\r\n```\r\nexport type NavigationEventSubscriber = (\r\n  eventName: string,\r\n  eventHandler: (payload: NavigationEventPayload) => void\r\n) => {\r\n  +remove: () => void,\r\n};\r\n```\r\n\r\n## Event Payload\r\n\r\nEach event will emit a payload of the same shape, with the following type:\r\n\r\n```\r\ntype NavigationEventPayload = {|\r\n  +state: NavigationState,\r\n  +lastState: NavigationState,\r\n  +action: NavigationAction,\r\n|};\r\n```\r\n\r\nThis shows the previous and current state of the navigation route, and the action that was fired.\r\n\r\n## Top-Level \"action\" Event\r\n\r\nThe \"action\" event will be emitted for _every_ navigation prop, when an action attempts to change the navigation state. The event only fires for the navigation state of the particular screen/navigator.\r\n\r\nIn some cases, the navigation state has not changed and `props.navigation.state === newState`. One example of this is the 'maySwipeBack' action fired by the stack navigator, which will be implemented in a following proposal.\r\n\r\n## Navigator Events\r\n\r\nThe following events will available to all screens inside of navigators. Navigators will implement these additional actions by subscribing to its own `onAction` event from `props.navigation.addListener`.\r\n\r\n### willFocus\r\n\r\nCalled when a screen will become focused, after it is mounted. Will be re-called when returning to the screen. Useful for starting to subscribe to new data.\r\n\r\nonWillFocus may be called extra times, which is considered 'refocusing', which is most commonly tapping on a tab that is already selected. On iOS this extra focus may result in scroll-to-top behavior.\r\n\r\n### didFocus\r\n\r\nCalled after the transition of focusing the screen. May be useful for input autofocus that waits for the transition to complete before focusing, or any other animation that should happen when the screen finishes becoming active.\r\n\r\n### willBlur\r\n\r\nThe screen will be popping or another screen may become active. At this point screens may unsubscribe from heavy data subscriptions or APIs.\r\n\r\n### didBlur\r\n\r\nThe screen is fully invisible now. This action will NOT fire when a screen is unmounted, for example at the end of a pop transition.\r\n\r\n## \"Is Transitioning\" State\r\n\r\nThe nav state will be augmented with the `isTransitioning` flag to notify subscribers when a navigation animation is happening. The new structure of a navigation state (/route) is:\r\n\r\n```\r\ntype NavigationState = {\r\n  index: number,\r\n  routes: Array<NavigationRoute>,\r\n  isTransitioning: boolean,\r\n};\r\n```\r\n\r\nWhen an animated transition begins, the index/routes change, and isTransitioning is toggled to true. If it does not switch to true, the navigation happens immediately without animation.\r\n\r\nThere will be a new navigation action for transition completion: 'CompleteTransitionAction', which toggles the `isTransitioning` boolean to false. This is done by StackNavigator, or any navigator once the transition completes.\r\n\r\nThis augmented state and new completion action is useful for navigators to provide the correct focus/blur events to children.\r\n\r\n## Immediate Navigation Actions\r\n\r\nThe \"Navigate\" and \"Back\" actions will automatically set `isTransitioning: true`. To override this behavior and request an immediate transition without animation, you can provide a new `immediate: true` option to the navigate and back actions, and the action will leave `isTransitioning` as false.\r\n"},"comment":{"url":"https://api.github.com/repos/react-navigation/react-navigation/issues/comments/363070837","html_url":"https://github.com/react-navigation/react-navigation/pull/3345#issuecomment-363070837","issue_url":"https://api.github.com/repos/react-navigation/react-navigation/issues/3345","id":363070837,"user":{"login":"DeanmvSG","id":15265711,"avatar_url":"https://avatars1.githubusercontent.com/u/15265711?v=4","gravatar_id":"","url":"https://api.github.com/users/DeanmvSG","html_url":"https://github.com/DeanmvSG","followers_url":"https://api.github.com/users/DeanmvSG/followers","following_url":"https://api.github.com/users/DeanmvSG/following{/other_user}","gists_url":"https://api.github.com/users/DeanmvSG/gists{/gist_id}","starred_url":"https://api.github.com/users/DeanmvSG/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/DeanmvSG/subscriptions","organizations_url":"https://api.github.com/users/DeanmvSG/orgs","repos_url":"https://api.github.com/users/DeanmvSG/repos","events_url":"https://api.github.com/users/DeanmvSG/events{/privacy}","received_events_url":"https://api.github.com/users/DeanmvSG/received_events","type":"User","site_admin":false},"created_at":"2018-02-05T12:29:04Z","updated_at":"2018-02-05T12:29:04Z","author_association":"NONE","body":"Is there a demo of this working within a mixed Stack/Tab Navigator setup?  My setup is as follows:\r\n\r\nStackNavigator (Login or Logged In) -> Tab Navigator (DashboardStack, SettingsStack etc) -> Each tab then has its own Stack Navigator (Dashboard Page).\r\n\r\nI've implemented the above setup for `willFocus` and `willBlur` onto the Dashboard page and it works for when moving through the DashboardStack, but not when moving from one Tab to another via the Tab Navigator."}}
{"actor":{"display_login":"DeanmvSG"}}