From e3ad1979320c7ed1f75825219136b6bc9cc12ef6 Mon Sep 17 00:00:00 2001 From: Jon Samp Date: Thu, 27 Dec 2018 20:54:25 -0500 Subject: [PATCH 1/4] adds guide, action on focus --- .../action-after-focusing-screen.md | 81 +++++++++++++++++++ .../version-3.x-sidebars.json | 3 +- 2 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 website/versioned_docs/version-3.x/action-after-focusing-screen.md diff --git a/website/versioned_docs/version-3.x/action-after-focusing-screen.md b/website/versioned_docs/version-3.x/action-after-focusing-screen.md new file mode 100644 index 00000000000..2bc6c633e85 --- /dev/null +++ b/website/versioned_docs/version-3.x/action-after-focusing-screen.md @@ -0,0 +1,81 @@ +--- +id: version-3.x-action-after-focusing-screen +title: Call an Action After Focusing Screen +sidebar_label: Action After Focusing Screen +original_id: action-after-focusing-screen +--- + +In this guide, we will call an action on screen focusing. This is useful for making additional API calls when a user visits a particular screen in a Tab Navigator, or to track user events as they tap around our app. + +There are two approaches to calling an action on screen focusing: + +1. Using the `withNavigationFocus` higher order component provided by react-navigation. +2. Listening to the `'didFocus'` event with an event listener. + +## Triggering an action with a higher order component + +react-navigation provides a [higher order component](https://reactjs.org/docs/higher-order-components.html) that passes a `isFocused` to our component, along with the `navigation` object we'd normally get with `withNavigation`. + +When the prop `isFocused` is passed to our component, it will pass `true` when the screen is focused and `false` when our component is no longer focused. This enables us to call functions on a user entering or leaving a screen. + +### Example + +```js +import React, { Component } from "react"; +import { View } from "react-native"; +import { withNavigationFocus } from "react-navigation"; + +class TabScreen extends Component { + componentDidUpdate(prevProps) { + if (prevProps.isFocused !== this.props.isFocused) { + // Use the `this.props.isFocused` boolean + // Call any action + } + } + + render() { + return ; + } +} + +// withNavigationFocus returns a component that wraps TabScreen and passes +// in the navigation prop +export default withNavigationFocus(TabScreen); +``` + +This example is also documented in the `withNavigationFocus` API documentation. + +## Triggering an action with an event listener + +We can also listen to the `'didFocus'` event with an event listener. After setting up an event listener, we must also stop listening to the event when the screen is unmounted. + +With this approach, we will only be able to call an action when the screen focuses. + +### Example + +```js +import React, { Component } from "react"; +import { View } from "react-native"; +import { withNavigation } from "react-navigation"; + +class TabScreen extends Component { + componentDidMount() { + const { navigation } = this.props; + this.focusListener = navigation.addListener("didFocus", () => { + // The screen is focused + // Call any action + }); + } + + componentWillUnmount() { + // Remove the event listener + this.focusListener.remove(); + } + + render() { + return ; + } +} + +export default withNavigation(TabScreen); +``` diff --git a/website/versioned_sidebars/version-3.x-sidebars.json b/website/versioned_sidebars/version-3.x-sidebars.json index f4e67285429..5d0392725e0 100644 --- a/website/versioned_sidebars/version-3.x-sidebars.json +++ b/website/versioned_sidebars/version-3.x-sidebars.json @@ -30,7 +30,8 @@ "version-3.x-screen-tracking", "version-3.x-state-persistence", "version-3.x-redux-integration", - "version-3.x-web-support" + "version-3.x-web-support", + "version-3.x-action-after-focusing-screen" ], "Build your own Navigator": [ "version-3.x-custom-navigator-overview", From 96f1bdee5205bc6eb51aba055f580bf75b27d0c3 Mon Sep 17 00:00:00 2001 From: Jon Samp Date: Fri, 28 Dec 2018 10:48:11 -0500 Subject: [PATCH 2/4] update link --- .../version-3.x/action-after-focusing-screen.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/website/versioned_docs/version-3.x/action-after-focusing-screen.md b/website/versioned_docs/version-3.x/action-after-focusing-screen.md index 2bc6c633e85..eb94c574d67 100644 --- a/website/versioned_docs/version-3.x/action-after-focusing-screen.md +++ b/website/versioned_docs/version-3.x/action-after-focusing-screen.md @@ -5,18 +5,18 @@ sidebar_label: Action After Focusing Screen original_id: action-after-focusing-screen --- -In this guide, we will call an action on screen focusing. This is useful for making additional API calls when a user visits a particular screen in a Tab Navigator, or to track user events as they tap around our app. +In this guide we will call an action on screen focusing. This is useful for making additional API calls when a user revisits a particular screen in a Tab Navigator, or to track user events as they tap around our app. There are two approaches to calling an action on screen focusing: 1. Using the `withNavigationFocus` higher order component provided by react-navigation. 2. Listening to the `'didFocus'` event with an event listener. -## Triggering an action with a higher order component +## Triggering an action with the `withNavigationFocus` higher order component -react-navigation provides a [higher order component](https://reactjs.org/docs/higher-order-components.html) that passes a `isFocused` to our component, along with the `navigation` object we'd normally get with `withNavigation`. +react-navigation provides a [higher order component](https://reactjs.org/docs/higher-order-components.html) that passes an `isFocused` prop to our component, along with the `navigation` object we'd normally get with `withNavigation`. -When the prop `isFocused` is passed to our component, it will pass `true` when the screen is focused and `false` when our component is no longer focused. This enables us to call functions on a user entering or leaving a screen. +When the `isFocused` prop is passed to our component, it will pass `true` when the screen is focused and `false` when our component is no longer focused. This enables us to call actions on a user entering or leaving a screen. ### Example @@ -43,9 +43,9 @@ class TabScreen extends Component { export default withNavigationFocus(TabScreen); ``` -This example is also documented in the `withNavigationFocus` API documentation. +This example is also documented in the `withNavigationFocus` API documentation. -## Triggering an action with an event listener +## Triggering an action with a `'didFocus'` event listener We can also listen to the `'didFocus'` event with an event listener. After setting up an event listener, we must also stop listening to the event when the screen is unmounted. From 35c9edb1c79db3242e4e53ee6c9dc549c90757b0 Mon Sep 17 00:00:00 2001 From: Jon Samp Date: Fri, 28 Dec 2018 18:45:45 -0500 Subject: [PATCH 3/4] feedback incorporation --- .../version-3.x/action-after-focusing-screen.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/website/versioned_docs/version-3.x/action-after-focusing-screen.md b/website/versioned_docs/version-3.x/action-after-focusing-screen.md index eb94c574d67..7873685554b 100644 --- a/website/versioned_docs/version-3.x/action-after-focusing-screen.md +++ b/website/versioned_docs/version-3.x/action-after-focusing-screen.md @@ -16,7 +16,11 @@ There are two approaches to calling an action on screen focusing: react-navigation provides a [higher order component](https://reactjs.org/docs/higher-order-components.html) that passes an `isFocused` prop to our component, along with the `navigation` object we'd normally get with `withNavigation`. -When the `isFocused` prop is passed to our component, it will pass `true` when the screen is focused and `false` when our component is no longer focused. This enables us to call actions on a user entering or leaving a screen. +When the `isFocused` prop is passed to our component, it will pass `true` when the screen is focused and `false` when our component is no longer focused. This enables us to call actions on a user entering or leaving a screen. This is particularly handy when we are trying to stop something when the page is unfocused, like stopping a video or audio file from playing, or stopping the tracking of a user's location. + +Since `withNavigationFocus` passes a prop on every focus change, it will cause our component to re-render when we focus and unfocus a screen. Using this higher order component may introduce unnecessary component re-renders as a screen comes in and out of focus. This could cause issues depending on the type of action we're calling on focusing. + +For instance, if we are attempting to make an API call on focus to fetch some data, we only want to fetch data when the component is focused and not when the component becomes unfocused. To prevent extra component re-renders, we could write some logic in `shouldComponentUpdate` to control when the component renders itself, however we may be better off using the event listener method detailed below. The event listener will only call an action and render the component when the screen is focused and will do nothing when a screen becomes unfocused. ### Example @@ -49,7 +53,7 @@ This example is also documented in the ; + } +} + +// withNavigationFocus returns a component that wraps TabScreen and passes +// in the navigation prop +export default withNavigationFocus(TabScreen); +``` + +This example is also documented in the `withNavigationFocus` API documentation. + +## Triggering an action with a `'didFocus'` event listener + +We can also listen to the `'didFocus'` event with an event listener. After setting up an event listener, we must also stop listening to the event when the screen is unmounted. + +With this approach, we will only be able to call an action when the screen focuses. This is great for fetching data with an API call when a screen becomes focused, or any other action that needs to happen once the screen comes into view. + +### Example + +```js +import React, { Component } from "react"; +import { View } from "react-native"; +import { withNavigation } from "react-navigation"; + +class TabScreen extends Component { + componentDidMount() { + const { navigation } = this.props; + this.focusListener = navigation.addListener("didFocus", () => { + // The screen is focused + // Call any action + }); + } + + componentWillUnmount() { + // Remove the event listener + this.focusListener.remove(); + } + + render() { + return ; + } +} + +export default withNavigation(TabScreen); +```