Develop/React Native

[React Native] react-navigation 화면이 포커스되었을 때를 감지하기 & 특정 화면에서 돌아왔을 때 api 호출하기

안다희 2020. 7. 1. 07:49
728x90

1. To Do

A screen에서 B screen으로 navigate한 후 다시 A로 goBack했을 때 goBack한 순간 A screen에서 api 호출을 다시 해야한다.

(C screen에서 A screen으로 오면 아무것도 하지 않는다)

 

2. How To

2-1. react navigation 활용 (해결책x)

https://reactnavigation.org/docs/function-after-focusing-screen/

 

React Navigation

In this guide we will call a function or render something 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.

reactnavigation.org

 

react-navigation은 아래에 보이듯이 총 3가지 방법을 제공한다. 

  1. Listening to the 'focus' event with an event listener.
  2. Using the useFocusEffect hook provided by react-navigation.
  3. Using the useIsFocused hook provided by react-navigation.

이 중에 react-navigation은 2번을 추천해서 2번을이용해보았다. 스낵 예제를 참고

Try this example on Snack

 

Snack - React Native in the browser

Try this project on your phone! Use Expo's online editor to make changes and save your own copy.

snack.expo.io

그러나 C screen에서 A screen에서 왔을 때도 감지를 하므로 이건 해결책이 될 수 없다!

 

 

2-2. DeviceEventEmitter 활용 (해결책 o)

 

https://github.com/react-navigation/react-navigation/issues/684

 

goBack detect stackNavigator · Issue #684 · react-navigation/react-navigation

Screen A -> Screen B On Screen B after I fill in a form, I use goBack() to go back to Screen A. However upon going back to Screen A, I need to refresh its contents. From Screen A, how can I dete...

github.com

A screen에서 api를 재호출하는건 B screen에서 A screen으로 왔을 때만 진행되어야 하므로 DeviceEventEmitter가 더 적당하다.

 

- A screen

  import React, { useEffect } from 'react';
  import { DeviceEventEmitter } from 'react-native';

  useEffect(() => {
    DeviceEventEmitter.addListener('abc', () => {
      alert('A screen from B screen')
    })
  }, []);

 

- B screen

  import React, { useEffect } from 'react';
  import { DeviceEventEmitter } from 'react-native';

  useEffect(() => {
    return () => {
      DeviceEventEmitter.emit('abc');
    }
  }, []);
  
  

 

이렇게 하면 B screen이 unmount 될 때 A screen에서 등록해놓은 리스너가 동작하고, C screen에서 A screen으로 왔을 때 emit을 하지 않기 때문에 내가 의도한대로 동작한다!

 

 

Buy Me A Coffee!

https://www.buymeacoffee.com/daheeahn

 

출처: https://mingos-habitat.tistory.com/34 [밍고의서식지:티스토리]