티스토리 뷰

react-native-router-flux 라이브러리를 사용하면서 발생했던 이슈 몇 가지가 있었다.

1. 두 번 이상의 클릭으로 새로운 스크린을 띄우게 되면 그 갯수만큼 스크린이 열림. (2번 누르면 2개 열림)
2. 창 닫기 버튼을 두 번 이상 클릭 했을 때 Actions.pop()이 여러번 호출 되는 증상. (2번 닫기버튼 누르면 2개 스크린이 닫힘)

3. 안드로이드에서 Back 버튼 두 번 누를 때 종료하는 기능

 

 

각각을 다음과 같이 해결함! 

 

두 번 이상의 클릭으로 새로운 스크린을 띄우게 되면 그 갯수만큼 스크린이 열리는 증상 

actions.js를 생성 후 다음과 같이 push함수를 정의한다. (현재 스크린의 키 값과 비교 후 이미 띄워졌다면 수행하지 않는 코드)

출처 (github.com/aksonov/react-native-router-flux/issues/2228)

import {Actions} from 'react-native-router-flux';

export const push = (destinationScene, props) => {
  // console.log('push', destinationScene, Actions.currentScene, props);
  if (Actions.currentScene === destinationScene) {
    return;
  }
  return Actions[destinationScene](props);
};

그리고 다음과 같이 사용

import {push} from './actions';

push('HomeScreen', {data: 'data'});

 

 

창 닫기 버튼을 두 번 이상 클릭 했을 때 Actions.pop()이 여러번 호출 되는 증상

actions.js에 열릴 때와 마찬가지로 'popScreen'이라는 함수를 하나 만들어주고 

export const popScreen = currentSceneName => {
  if (Actions.currentScene !== currentSceneName) {
    return;
  }

  return Actions.pop();
};

다음과 같이 현재 스크린의 scene key를 넣어주는 방식으로 사용하면, 두 번 호출이 되지 않는다! 

import {popScreen} from './actions';

popScreen('HomeScreen');

 

 

안드로이드에서 Back 버튼 두 번 누를 때 종료하는 기능 

App.js에 다음과 같이 BackHandler 이벤트를 등록 (Scene key가 HomeScreen이거나 LoginScreen일 때만 handleBackButton이 수행되도록 함)

import {BackHandler} from 'react-native';

export default class App extends Component {
	constructor(props) {
    	super(props);
        this.exitApp = false;
        BackHandler.addEventListener('hardwareBackPress', () => {
          console.log('Actions.currentScene', Actions.currentScene);
          switch (Actions.currentScene) {
            // HomeScreen과 LoginScreen에서만 백 버튼을 disabled하고, 여기서 이벤트를 처리하도록 하자!!
            case 'HomeScreen':
            case 'LoginScreen': {
              this.handleBackButton();
              break;
            }

            default: {
				//noop
            }
          }
        });
    }
    
    handleBackButton = () => {
      // 2000(2초) 안에 back 버튼을 한번 더 클릭 할 경우 앱 종료
      if (this.exitApp === undefined || !this.exitApp) {
        ToastAndroid.show('한번 더 누르시면 종료됩니다.', ToastAndroid.SHORT);
        this.exitApp = true;
        this.timeout = setTimeout(
          () => {
            this.exitApp = false;
          },
          2000, // 2초
        );
      } else {
        clearTimeout(this.timeout);
        BackHandler.exitApp(); // 앱 종료
      }
      return true;
    };
    
    // 컴포넌트 지워질 때 이벤트도 지워주자
    componentWillUnmount(): void {
        BackHandler.removeEventListener('hardwareBackPress', () => {});
    }
}

 그리고 HomeScreen과 LoginScreen에서는 react-native-router-flux의 기본 back버튼 이벤트가 발생하면 안되므로, Scene을 등록해준 코드에서 다음과같이 back버튼 이벤트를 비활성화 해준다 

import HomeScreen from './HomeScreen';
import LoginScreen from './LoginScreen';

...

<Router>
	<Scene key='root'>
    	<Scene
        	key='LoginScreen'
            component={LoginScreen}
            type={ActionConst.RESET} // 이 줄이 해당 스크린에서 Back버튼 이벤트를 비활성화 
        />
    
    	<Scene
        	key='HomeScreen'
            component={HomeScreen}
            type={ActionConst.RESET} // 이 줄이 해당 스크린에서 Back버튼 이벤트를 비활성화 
        />
    </Scene>
</Router>

...

그럼 LoginScreen과 HomeScreen에서는 두 번 연속으로 눌러야 종료가 되고, 나머지에서는 일반적인 방식으로 동작한다.

반응형
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함