I have a coding error in my application, yet it was not easily discovered because the errorReporter seems to be failing to render it.
I receive these messages in the log:
Warning: React.createElement: type should not be null, undefined, boolean, or number. It should be a string (for DOM elements) or a ReactClass (for composite components). Check the render method of `AppContainer`.
Uncaught Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object. Check the render method of `AppContainer`.
I edited my local AppContainer.dev.js to output the actual source error:
console.log("error: ", error, " typeof: ", typeof error)
console.log("errorReporter: ", this.props.errorReporter, " typeof: " + typeof this.props.errorReporter)
return React.createElement(this.props.errorReporter, { error: error });
And I receive the source error and additional information:
error: TypeError: Cannot read property 'replace' of undefined
at module.exports (eval at <anonymous> (http://localhost:3808/webpack/application.js:8112:2), <anonymous>:14:19)
at module.exports (eval at <anonymous> (http://localhost:3808/webpack/application.js:8106:2), <anonymous>:10:21)
at new JwtToken (eval at <anonymous> (http://localhost:3808/webpack/application.js:8100:2), <anonymous>:47:43)
at Security.getJwtToken (eval at <anonymous> (http://localhost:3808/webpack/application.js:8052:2), <anonymous>:196:27)
at Security.ensureInitialWorkingTime (eval at <anonymous> (http://localhost:3808/webpack/application.js:8052:2), <anonymous>:123:12)
at App.componentWillMount (eval at <anonymous> (http://localhost:3808/webpack/application.js:4764:2), <anonymous>:126:26)
at App.componentWillMount (eval at <anonymous> (http://localhost:3808/webpack/application.js:1542:2), <anonymous>:44:30)
at ReactCompositeComponentWrapper.performInitialMount (eval at <anonymous> (http://localhost:3808/webpack/application.js:4452:2), <anonymous>:336:12)
at ReactCompositeComponentWrapper.mountComponent (eval at <anonymous> (http://localhost:3808/webpack/application.js:4452:2), <anonymous>:244:21)
at Object.mountComponent (eval at <anonymous> (http://localhost:3808/webpack/application.js:4104:2), <anonymous>:46:35)
typeof: object
errorReporter: Object {__RewireAPI__: Object, __esModule: true} typeof: object
I'm not sure what errorReporter is expecting, perhaps it needs to typecheck or stringify the error before attempting to render?
@rosskevin I'm experiencing the same thing. Haven't had a chance to dig in yet though.
This is killing me!
It seems to be caused by many things. A certain way to trigger it is this:
class Foo extends React.Component {
constructor() {
super();
this.x = this.x.bind(this);
}
where x does not exist.
or similar with destructuring:
const { foo } = props.x;
where x does not exists in props.
I ran into this today and it seems that the cause relates to the way Redbox is being imported.
https://github.com/gaearon/react-hot-loader/blob/next/src/AppContainer.dev.js#L5
const Redbox = require('redbox-react');
However, this needs to be:
const Redbox = require('redbox-react').default;
You can also work around this _in your app_ by installing redbox-react in your project and doing this (as this will refer to the default export):
import Redbox from "redbox-react";
<AppContainer errorReporter={Redbox}>
...
</AppContainer>
This might be due to a recent change in the way redbox-react exports itself or something? I'm not sure if this is the correct way to fix the above.
Any ideas?
Hadn't noticed #314. I believe that's exactly the problem and fix.
@dpwrussell it's fixed in #314
@nathanmarks Thanks. I already implemented @harmony7 (Thanks!) workaround until #314 makes it into a release.
redbox is very inconvenient to use as it doesn't really use the built in error handling of the browser - basically no sourcemap stacktraces.
It also doesn't look good when using chrome's mobile emulator (it's too small to really see anything).
can we instead do this in AppContainer.dev :
if (error) {
console.error(error.message,error.stack);
return React.createElement(this.props.errorReporter, { error: error });
}
at least we'll get nice stack traces alongside it.
In the meantime before the pull request for this is merged in, i've done something like this:
import React, { PropTypes } from 'react';
import RedBox from 'redbox-react';
const WrappedRedBox = ({ error }) => {
if (error) {
console.error(error.message, error.stack); // eslint-disable-line no-console
}
return <RedBox error={error}/>;
};
WrappedRedBox .propTypes = {
error: PropTypes.instanceOf(Error).isRequired,
};
export default WrappedRedBox ;
Then added it in the AppContainer errorReporter prop.
<AppContainer errorReporter={WrappedRedBox}>
...
</AppContainer>
Fixed by #314 and out in 3.0.0-beta.3.
Finally! Thank you so much @calesce
Most helpful comment
I ran into this today and it seems that the cause relates to the way Redbox is being imported.
https://github.com/gaearon/react-hot-loader/blob/next/src/AppContainer.dev.js#L5
However, this needs to be:
You can also work around this _in your app_ by installing
redbox-reactin your project and doing this (as this will refer to the default export):This might be due to a recent change in the way redbox-react exports itself or something? I'm not sure if this is the correct way to fix the above.
Any ideas?