
I met this error. When I refresh several times, sometimes it runs.
This is my files
// reactoron-config.js
import Reactotron, { trackGlobalErrors } from 'reactotron-react-native';
import apisaucePlugin from 'reactotron-apisauce'; // <--- import
import { reactotronRedux } from 'reactotron-redux';
import sagaPlugin from 'reactotron-redux-saga';
console.tron = Reactotron;
Reactotron
.configure() // we can use plugins here -- more on this later
.use(trackGlobalErrors()) // <--- here we go!
.use(apisaucePlugin())
.use(reactotronRedux())
.use(sagaPlugin())
.connect(); // let's connect!
export default Reactotron;
// configureStore.js
import { applyMiddleware, compose } from 'redux';
import createSagaMiddleware from 'redux-saga';
import thunk from 'redux-thunk';
import Reactotron from '../../env/reactotron-config';
import reducers from '../ducks';
import rootSaga from '../saga';
import googleAnalytics from './middleware/googleAnalytics';
const isDebuggingInChrome = __DEV__ && !!window.navigator.userAgent;
const sagaMonitor = Reactotron.createSagaMonitor();
function configureStore(onComplete) {
const sagaMiddleware = createSagaMiddleware({ sagaMonitor });
const store = Reactotron.createStore(reducers, {}, compose(
applyMiddleware(sagaMiddleware, thunk, googleAnalytics),
));
sagaMiddleware.run(rootSaga);
if (isDebuggingInChrome) {
window.store = store;
}
setTimeout(() => {
onComplete(store.getState());
});
return store;
}
// Setup.js
class Setup extends Component {
constructor() {
super();
GoogleAnalytics.setTrackerId('UA-86299762-1');
this.state = {
isLoading: true,
store: configureStore((state) => {
this.setState({ isLoading: false });
if (state.user.nickname) {
const { nickname, school } = state.user;
GoogleAnalytics.setUser(nickname);
setCrashlytics(nickname, school);
}
}),
};
// console.disableYellowBox = true;
}
render() {
if (this.state.isLoading) {
return <LoadingScreen />;
}
return (
<Provider store={this.state.store}>
<App />
</Provider>
);
}
}
RN version: 0.38
reactotron-react-native: 1.6.0
reactotron-redux: 1.6.1
Seems like the store isn't quite setup before accepting the first command. I'd recommend moving the store creation out of the constructor to decouple it from React's components.
@skellock thanks. I solved this problem.
@skellock I'm incurring in the same error. How did you solve it?
I only changed my code like this.
const store = configureStore();
class Setup extends Component {
render() {
return (
<Provider store={store}>
<App />
</Provider>
);
}
}
Thanks @g6ling I ended up with that solution as well. I had to mangle with the callback in the configureStore
@fabriziogiordano
This is my App.js
export default compose(
codePush,
connect((state) => ({
loaded: state.setInitial.loaded,
}), (dispatch, props) => ({
...props,
setInitialState: () => dispatch(setInitialState()),
})),
)(class App extends Component {
componentWillMount() {
this.props.setInitialState();
}
render() {
if (this.props.loaded === false) {
return <LoadingScreen />;
}
return (
<Route />
);
}
});
First, I set initialState with only JS object not redux-persist, realm. setInitialState() is action for asynchronously set Initial store. In my case, I used Realm and redux-saga.
function* setRealm() {
const setRealmArray = [
put({ type: SET_REALM_SCHEDULE, payload: ScheduleItems }),
put({ type: SET_REALM_SETTING,
payload: {
schedule: Setting[0].schedule[0],
} }),
];
if (User[0]) {
setRealmArray.push(put({ type: SET_REALM_USER, payload: User[0] }));
}
try {
yield setRealmArray;
yield put({ type: SET_REALM_SUCCESS });
} catch (error) {
yield put({ type: SET_REALM_FAIL, payload: error });
}
}
const setSessionPromise = (session) => new Promise((resolve) => {
setSession(session);
resolve(true);
});
export const setAnalytics = (user) => new Promise((resolve) => {
if (!user.nickname) {
GoogleAnalytics.setUser('guest');
setCrashlytics('guest', 'guest');
} else {
GoogleAnalytics.setUser(user.nickname);
setCrashlytics(user.nickname, user.school);
}
resolve(true);
});
function* setApi() {
try {
const selectUser = (state) => state.user;
const user = yield select(selectUser);
if (user.session) {
yield call(setSessionPromise, user.session);
setSessionPromise(user.session);
}
yield call(setAnalytics, user);
const FirebaseInitialize = () => Firebase.initialize();
yield call(FirebaseInitialize);
yield put({ type: SET_API_SUCCESS });
} catch (error) {
yield put({ type: SET_API_FAIL, payload: error });
}
}
export function* setInitialState() {
yield call(setRealm);
yield call(setApi);
yield put({ type: LISTEN_FIREBASE });
yield put({ type: SET_INITIAL_STATE_SUCCESS });
}
export default function* watch() {
yield takeLatest(SET_INITIAL_STATE, setInitialState);
}
const reducer = handleActions({
[SET_INITIAL_STATE_SUCCESS]: (state) => ({
...state,
loaded: true,
}),
}, initialState);
This is my code. I don't use callback only use action.
You make store outside react component and update your store in component. So you can use callback.
class App extends Component {
state = { loaded: false}
componentWillMount() {
updateStore(()=> { this.setState({ loaded: true }); });
}
render() {
if (this.state.loaded === false) {
return <LoadingScreen />;
}
return (
<Route />
);
}
}
I am having this issue as well. Not really sure why. I create my store before any components.
Try moving the Reactotron.connect() into the componentWillMount() of your first component. Same thing?
@g6ling thanks. I solved this problem.
@skellock That solved it for me. Thanks.
Reactotron setup still happens in my config file, only the connect() moves to cwm:
if (__DEV__) Reactotron.connect();
Not quite sure what the issue is, but it definitely feels like a bug on our end. Some weird timing thing where the store is created, but something else isn鈥檛 quite initialized.
Indeed, calling connect() too early gives me the same bug
I fixed this flow the document
https://github.com/infinitered/reactotron/blob/master/docs/plugin-redux.md
Then, where you create your Redux store, instead of using Redux's createStore, you can use Reactotron's createStore which has the same interface.
const store = Reactotron.createStore(rootReducer, compose(middleware))
That solved the issue, thanks @skellock!
is there any update for this open item? Already try to move it to componentWillMount but still throwing that error only when Reactotron open. Very weird
@ferroblesh same problem here...
Depending on your module load order, redux might not be fully initialized before that connection from reactotron comes in. It鈥檚 super subtle because of the hoisting of imports and depth-first traversal of modules that happens in react native.
Try deferring your connect() call until everything (specifically redux) has been setup. This can be in root component鈥檚 componentDidMount (for example).
is Reactotron works with react: 16.2 and react-native: 0.52.1 ??
I am trying to do this in my ComponentDidMount(), but I still see this error. Do you guys have any sample?
Fails at RootComponent::componenDidMount(). Even setTimeout(() => Reactotron.connect(), 5000) didn't help.
..
Got it working with this:
const store = __DEV__
? Reactotron.createStore(reducers, enchancers(applyMiddleware(sagaMiddleware)))
: createStore(reducers, enchancers(applyMiddleware(sagaMiddleware)))
const createAppropriateStore = Config.useReactotron
? console.tron.createStore
: createStore;
const store = createAppropriateStore(reducers, undefined, compose(...enhancers));
Calling .connect() after .createStore() fixed the error for me. I'm not sure if it's that call order or simply delay calling .connect() solved the problem, but definitely there was a weird race condition in the background.
This should be clearly documented.
This is very stupid on my part but I hope it helps someone. 9/10 times I see this error when I've made a typo in the object passed into the StyleSheet.create. This latest time around I put quotes around a field that was expecting an integer.
Most helpful comment
is there any update for this open item? Already try to move it to componentWillMount but still throwing that error only when Reactotron open. Very weird