리액트 네이티브로 앱 개발을 진행할 때 기본적으로 사용할 수 있는 크롬 개발자 도구로도 불편함을 느끼지 못했다면 모르겠지만, 제공해 주는 정보가 빈약하고, 에뮬레이터에서 개발자 도구를 띄워서 사용하기는 불편하기 때문에 추가적으로 디버깅 환경을 구성할 필요가 있다.
오늘 설치할 Reactotron은 ReactJS에서도 사용할 수 있다.
이를 사용하면 RN에서도 콘솔을 사용할 수 있고, 코드 상에서 에러가 발생한 위치를 알려주는 등 다양한 기능을 지원하기 때문에 이를 사용해 디버깅 환경을 구성할 것이다.
터미널에 아래 명령어를 입력하여 reactotron 어플리케이션을 설치할 것이다.
OS는 맥, homebrew는 3.4.6버전 기준으로 진행했으며, --cask 옵션을 통해 gui 어플리케이션을 설치할 수 있다.
brew install --cask reactotron
정상적으로 설치되었다면 어플리케이션 폴더에 Reactotron.app이 생성되었을 것이다.
Reactotron이 정상적으로 설치되었다면, 이제 프로젝트에 Reactotron을 연동할 것이다.
아래 명령어를 실행하여 React Native와 Reactotron을 연동하기 위한 패키지를 설치하자.
npm i --save-dev reactotron-react-native
패키지가 설치가 완료 되었다면 프로젝트 내에 ReactotronConfig.js
파일을 생성한다.
Reactotron 공식문서에는 다음과 같이 작성하라고 적혀있다.
import Reactotron from 'reactotron-react-native';
Reactotron.configure() // AsyncStorage would either come from `react-native` or `@react-native-community/async-storage` depending on where you get it from // controls connection & communication settings
.useReactNative() // add all built-in react native plugins
.connect(); // let's connect!
이후 App.js
나 index.js
와 같은 루트 소스에 ReactotronConfig.js
를 불러와 적용시키면 끝이다.
import Reactotron from 'reactotron-react-native';
if (__DEV__) {
import('./ReactotronConfig').then(() => Reactotron.log('Reactotron Configured'));
}
위 코드를 모두 적용한 후 앱을 빌드한 후 실행하고 Reactotron도 동시에 실행시켜준다.
Reactotron에
'Reactotron Configured'
이라는 문구가 표시된다면 정상적으로 연동된 것이다.
하지만 안드로이드 앱 빌드 시에 틀린 부분 없이 설정을 완료했음에도 연동이 되지 않는다면 안드로이드 에뮬레이터와 Reactotron이 사용하는 9090포트로 연결되지 않았을 가능성이 있다.
이때는 package.json
에서 다음과 같이 작성한다.
"scripts": {
"android": "adb reverse tcp:9090 tcp:9090 && react-native run-android",
...
이후 npm run android
명령어로 안드로이드로 빌드해 실행하면 정상적으로 연동될 것이다.
내가 현재 진행하고 있는 프로젝트는 store로 redux를 사용하고 있다.
Reactotron에서는 이 redux 스토어에서 일어나는 action과 같은 state의 변경을 확인할 수 있다.
이를 연동하기 위해서는 먼저 Reactotron과 Redux 연동 패키지를 프로젝트에 설치한다.
npm i --save-dev reactotron-redux
설치가 완료되었다면 ReactotronConfig.js
를 아래처럼 수정한다.
import Reactotron from 'reactotron-react-native';
import { reactotronRedux } from 'reactotron-redux';
const reactotron = Reactotron
.configure() // AsyncStorage would either come from `react-native` or `@react-native-community/async-storage` depending on where you get it from // controls connection & communication settings
.use(reactotronRedux()) // set Redux(추가)
.useReactNative() // add all built-in react native plugins
.connect(); // let's connect!
export default reactotron;
다음은 redux store를 생성하는 createStore(...)
가 작성된 코드로 이동해 아래처럼 수정하면 된다.
이 프로젝트의 경우는 ./store/index.js
에 위치해 있다.
//before
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './modules';
const store = createStore(rootReducer, applyMiddleware(thunk));
export default store;
//after
import { createStore, applyMiddleware, compose } from 'redux'; //compose 추가
import thunk from 'redux-thunk';
import Reactotron from '../../ReactotronConfig'; //added
import rootReducer from './modules';
const store = createStore(rootReducer, compose(applyMiddleware(thunk), Reactotron.createEnhancer())); // create store with reactotron
export default store;
만약 thunk와 같은 추가적인 미들웨어를 redux에 적용하고 있었다면, compose
를 redux에서 import해 위의 코드처럼 여러 미들웨어를 하나로 묶어 생성할 스토어에 적용할 수 있다.