2

I'm developing an application using create-react-app and I'm trying to split my code into modules implementing the way described in the react-router huge-apps example. Everything works well except the unit tests : I get this error while running the jest tests for the route components :

TypeError: Cannot read property 'contextTypes' of undefined

A route component looks like this :

export class IntroPage extends React.Component {
    render() {
        return (
            <div></div>
        );
    }
}

const mapStateToProps = (state) => {
    return {
        ...
    }
};

module.exports = connect(mapStateToProps)(IntroPage);

and a test :

import React from 'react';
import {shallow} from 'enzyme';
import {IntroPage} from '../IntroPage';

it('should render without crashing', () => {
    shallow(
        <IntroPage {...props}/> // IntroPage is undefined
    )
});

How do I have to export/import my components to be able to test them properly.

Thanks.

5
  • Why are you using both ES6 export syntax and CommonJS module.exports in one file? This is not supported. Commented Jan 27, 2017 at 21:35
  • CommonJS syntax is supported for compatibility but you shouldn't use it in any new code. Mixing them is wrong semantically because they have conflicting meanings. Commented Jan 27, 2017 at 21:35
  • I know but if I export the component like I use to do in es6 (export default), it doesn't work. Commented Jan 27, 2017 at 21:38
  • I have to say my route definition looks like this : export default { childRoutes: [ { path: '/', component: require('./components/app/App') }, { path: '*', onEnter: (nextState, replace) => replace('/') } ] }; Commented Jan 27, 2017 at 21:39
  • This is the way exposed in the react-router example. Commented Jan 27, 2017 at 21:40

2 Answers 2

1

If you transpile in Babel:

export class IntroPage extends React.Component {
   ...
}

You will notice that Babel will move that to the exports variable.

Object.defineProperty(exports, "__esModule", {
    value: true
});
... more good stuff
...
var IntroPage = exports.IntroPage = function (_React$Component) {

So you can console.log these:

console.log(exports);
console.log(module.exports);
console.log(module);

and check exports variable and module object. In here module.exports should be the same as exports.

If you type:

 module.exports = connect(mapStateToProps)(IntroPage);

at the end of your component file, you are overwriting the module.exports with the new value.

This is the core of the problem.

The solution?

I think you already found one, but the best would be not to mix commonJS with ES6 export, since ES6 export will be transpiled to commonJS syntax.


Check also "What is export default in JavaScript?"

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks. I knew it was not a good idea to mix syntaxes but since it was the way it was done in the react-router example, I thought it was the good one. > but the best would be not to mix commonJS with ES6 exports What do you mean? I'm still mixing syntaxes with the solution I found? I thought I didn't.
BTW, react-router is not a superior product. It is heavy when you include it on a page and you cannot find it mentioned in the default react project documentation by Facebook, and more if you search for react router alternative you will find more reasons not to use it in the future.
Sure but I'm making my way step by step :)
0

Found a solution with this post : React router dynamic routes not rendering component

I just had to add 'default' to the require statements when exporting with es6 module.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.