Reference
https://github.com/infinitered/reactotron/blob/master/docs/tips.md
https://github.com/infinitered/reactotron/blob/master/docs/troubleshooting.md
Reactotron is a powerful debugger for React and React Native applications. It provides an easy-to-use interface for developers to monitor their application's state, network requests, and performance metrics and can be used for any size of project, from small personal apps to large-scale enterprise applications.
It has a powerful plugin system that allows developers to extend and enhance the capabilities of Reactotron.
You can use Reactotron to:
- view your application state
- show API requests & responses
- perform quick performance benchmarks
- subscribe to parts of your application state
- display messages similar to
console.log
- track global errors with source-mapped stack traces including saga stack traces!
- dispatch actions like a government-run mind control experiment
- hot swap your app's state using Redux or mobx-state-tree
- show image overlay in React Native
- track your Async Storage in React Native
You plug it into your app as a development dependency so it adds nothing to your production build size.
How to add to a React Native project
npm i -D reactotron-redux
npm i -D reactotron-react-native
Add to the index.js
import {AppRegistry} from 'react-native';
import ReduxWrappedApp from './src/App';
import {name as appName} from './app.json';
if (__DEV__) {
require("./ReactotronConfig");
}
AppRegistry.registerComponent(appName, () => ReduxWrappedApp);
In the root reducer
import { combineReducers } from 'redux';
import {configureStore} from '@reduxjs/toolkit';
import {devToolsEnhancer} from '@redux-devtools/remote';
import {Platform} from 'react-native';
import createSagaMiddleware from 'redux-saga';
import bangReducer from '../containers/Bang/redux/reducer';
import rootSaga from './sagas';
// SET UP THE REDUCER
const rootReducer = combineReducers(
{
bang: bangReducer
});
// MIDDLEWARE: SAGA
const sagaMiddleware = createSagaMiddleware();
// MIDDLEWARE: LOGGER
const loggerMiddleware = store => next => action => {
console.log('------------------------------------------------------');
console.group(action.type)
console.info('dispatching', action)
const result = next(action)
console.log('next state', store.getState())
console.groupEnd()
return result
};
// ENHANCERS
const enhancers = [];
enhancers.push(
devToolsEnhancer({
name: Platform.OS,
hostname: Platform.select({ ios: 'localhost', android: '10.0.2.2' }),
port: 8000,
secure: false,
realtime: true,
})
);
// CONFIGURE THE STORE
const store = () => {
const store = configureStore({
reducer: rootReducer,
middleware: (getDefaultMiddleware => getDefaultMiddleware({
thunk: false
})
.concat(loggerMiddleware)
.concat(sagaMiddleware)
),
enhancers: (getDefaultEnhancers) => {
return getDefaultEnhancers({
autoBatch: { type: 'tick' },
})
.concat(__DEV__ ? [require( '../../ReactotronConfig').default.createEnhancer()] : [])
},
});
sagaMiddleware.run(rootSaga)
return store;
};
export default store();
Notes:
Surround your Reactotron activities with:
if (__DEV__) {
// ZAP!
}
console.tron = Reactotron
Reactotron.log("something really interesting happened")
// or Reactotron.display
console.tron.display({
name: "Tacos",
value: { a: 1, b: [1, 2, 3] },
preview: "when you click here, it might surprise you!",
important: true,
image: "http://placekitten.com/g/400/400",
})
Custom Commands
// or Reactotron.display
console.tron.display({
name: "Tacos",
value: { a: 1, b: [1, 2, 3] },
preview: "when you click here, it might surprise you!",
important: true,
image: "http://placekitten.com/g/400/400",
})
Reactotron.onCustomCommand("test", () => console.log("This is an example"))
// Accept user input from Reactotron and navigate to that route:
Reactotron.onCustomCommand({
command: "navigateTo",
handler: (args) => {
const { route } = args
if (route) {
Reactotron.log(`Navigating to: ${route}`)
navigate(route)
} else {
Reactotron.log("Could not navigate. No route provided.")
}
},
title: "Navigate To Screen",
description: "Navigates to a screen by name.",
args: [
{
name: "route",
type: ArgType.String,
},
],
})
// Accept user input from Reactotron and navigate to that route:
Reactotron.onCustomCommand({
command: "navigateTo",
handler: (args) => {
const { route } = args
if (route) {
Reactotron.log(`Navigating to: ${route}`)
navigate(route)
} else {
Reactotron.log("Could not navigate. No route provided.")
}
},
title: "Navigate To Screen",
description: "Navigates to a screen by name.",
args: [
{
name: "route",
type: ArgType.String,
},
],
})