question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

npm test: setState in api callback: Cannot read property 'createEvent' of undefined

See original GitHub issue

Is this a bug report?

Yes

Can you also reproduce the problem with npm 4.x?

I am on 5.5.1 and it’s not npm related

Environment

node -v v9.2.0 npm ls react-scripts react-app@0.1.0 /opt/foxyboy/sw/pri/code-samples/react-test-error └── react-scripts@1.0.17 echo $(lsb_release --description --codename --short) Ubuntu 17.10 artful

Root Cause

I used npm t on a component using unmocked fetch, which of course fails. However, updating state in the catch clause causes a render with the global document value undefined

node_modules/react-dom/cjs/react-dom.development.js:577

var evt = document.createEvent('Event');

is this a bug?

Steps to Reproduce

  1. Fresh create-react-app
  2. modify index/App.js as below
  3. npm t
class App extends Component {
  constructor(...args) {
    super(...args)
    this.state = {}
  }

  componentDidMount() {
    this.myFetch().catch(e => this.setState({e}))
  }

  async myFetch() {
    await fetch('/proxiedApi')
  }

  render() {
    const {e} = this.state
    return (
      <div className="App">
        <header className="App-header">
          {/*<img src={logo} className="App-logo" alt="logo" />*/}
          <h1 className="App-title">Welcome to React</h1>
        </header>
        <p className="App-intro">
          To get started, edit <code>src/App.js</code> and save to reload.
        </p>
        {e && <p>Error: {String(e)}</p>}
      </div>
    );
  }
}

Expected Behavior

  1. The test to succeed
  2. The component to store the “right” error: TypeError: Network request failed properly

Actual Behavior

TypeError: Cannot read property ‘createEvent’ of undefined

 RUNS  src/App.test.js                    
/opt/foxyboy/sw/pri/code-samples/react-test-error/node_modules/react-scripts/scripts/test.js:20
  throw err;         
  ^                  

TypeError: Cannot read property 'createEvent' of undefined                          
    at Object.invokeGuardedCallbackDev (/opt/foxyboy/sw/pri/code-samples/react-test-error/node_modules/react-dom/cjs/react-dom.development.js:577:26)
    at invokeGuardedCallback (/opt/foxyboy/sw/pri/code-samples/react-test-error/node_modules/react-dom/cjs/react-dom.development.js:436:27)
    at renderRoot (/opt/foxyboy/sw/pri/code-samples/react-test-error/node_modules/react-dom/cjs/react-dom.development.js:10386:7)
    at performWorkOnRoot (/opt/foxyboy/sw/pri/code-samples/react-test-error/node_modules/react-dom/cjs/react-dom.development.js:11000:24)
    at performWork (/opt/foxyboy/sw/pri/code-samples/react-test-error/node_modules/react-dom/cjs/react-dom.development.js:10952:7)
    at requestWork (/opt/foxyboy/sw/pri/code-samples/react-test-error/node_modules/react-dom/cjs/react-dom.development.js:10861:7)
    at scheduleWorkImpl (/opt/foxyboy/sw/pri/code-samples/react-test-error/node_modules/react-dom/cjs/react-dom.development.js:10744:11)
    at scheduleWork (/opt/foxyboy/sw/pri/code-samples/react-test-error/node_modules/react-dom/cjs/react-dom.development.js:10706:12)
    at Object.enqueueSetState (/opt/foxyboy/sw/pri/code-samples/react-test-error/node_modules/react-dom/cjs/react-dom.development.js:6204:7)
    at App.Object.<anonymous>.Component.setState (/opt/foxyboy/sw/pri/code-samples/react-test-error/node_modules/react/cjs/react.development.js:226:16)
    at myFetch.catch.e (/opt/foxyboy/sw/pri/code-samples/react-test-error/src/App.js:12:36)
    at <anonymous>   
    at process._tickCallback (internal/process/next_tick.js:188:7)                  
npm ERR! Test failed.  See above for more details.                                  

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:5
  • Comments:12 (6 by maintainers)

github_iconTop GitHub Comments

7reactions
gaearoncommented, Nov 27, 2017

The problem is your test is now asynchronous but you don’t wait for it to finish. So by the time the callback runs, the environment is already cleaned up.

I think the right thing to do for us would be to explicitly unmount the component at the end of the test. For example:

it('renders without crashing', () => {
  const div = document.createElement('div');
  ReactDOM.render(<App />, div);
  ReactDOM.unmountComponentAtNode(div);
});

This would ensure only the initial render is being tested.

You’d still have the problem of a “dead callback” because you never actually cancel it. But you have this problem anyway regardless of tests. If a component starts some work, componentWillUnmount should cancel it. There is no easy way to do cancellation with fetch() API yet as far as I know (at least not until the polyfill updates), so you could set a field yourself:

class App extends Component {
  state = {};
  isMounted = false;

  async componentDidMount() {
    this.isMounted = true;
    try {
      await fetch('/proxiedApi');
    } catch(e) {
      if (this.isMounted) { // <--- don't call setState when unmounted
        this.setState({e});
      }
    }
  }

  componentWillUnmount() {
    this.isMounted = false; // <--- reset it on unmounting
  }

  render() {
    // ...
  }
}

This solution is not ideal but will work. A better one would be to actually cancel the fetch instead of ignoring it. When fetch API supports cancellation you can do this. Or you could use a library like axios that supports it today.

6reactions
haraldrudellcommented, Nov 22, 2017

getaround: check NODE_ENV

  componentDidMount() {
    if (process.env.NODE_ENV === 'test') return // TODO 171121: https://github.com/facebookincubator/create-react-app/issues/3482
Read more comments on GitHub >

github_iconTop Results From Across the Web

React, Jest, and Testing Library: TypeError: Cannot read ...
React, Jest, and Testing Library: TypeError: Cannot read property 'createEvent' of null when using findBy such as findByAltText · It was Testing ......
Read more >
[Solved]-Cannot read states in Redux with React Hooks ...
Coding example for the question Cannot read states in Redux with React Hooks, Cannot read property '_id' of null-Reactjs.
Read more >
useHooks - Easy to understand React Hook recipes
We bring you easy to understand React Hook code recipes so you can learn how React hooks work and feel more comfortable writing...
Read more >
Samatar on Twitter: "After upgrading to React 17, getting a lot ...
After upgrading to React 17, getting a lot of "TypeError: Cannot read property 'createEvent' of null" coming from react-dom when running ...
Read more >
How to use React createRef - LogRocket Blog
When working with refs in React, you may run into the problem — "TypeError: Cannot read properties of undefined" . This error can...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found