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.

untemps
  • 165
  • 2
  • 11
  • Why are you using both ES6 export syntax and CommonJS module.exports in one file? This is not supported. – Dan Abramov Jan 27 '17 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. – Dan Abramov Jan 27 '17 at 21:35
  • I know but if I export the component like I use to do in es6 (export default), it doesn't work. – untemps Jan 27 '17 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('/') } ] }; – untemps Jan 27 '17 at 21:39
  • This is the way exposed in the react-router example. – untemps Jan 27 '17 at 21:40

2 Answers2

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?"

Community
  • 1
  • 1
prosti
  • 42,291
  • 14
  • 186
  • 151
  • 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. – untemps Jan 30 '17 at 08:25
  • 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. – prosti Jan 30 '17 at 08:28
  • Sure but I'm making my way step by step :) – untemps Jan 30 '17 at 08:32
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.

Community
  • 1
  • 1
untemps
  • 165
  • 2
  • 11