React: React 15 update: Uncaught TypeError: Cannot read property 'addEventListener' of null

Created on 18 Apr 2016  路  32Comments  路  Source: facebook/react

Hello,

After updating to React 15.0.1, we are getting the following error:

Uncaught TypeError: Cannot read property 'addEventListener' of null

image

Most helpful comment

I just landed a fix for this (#6650) which will be in 15.0.3 or 15.1.0, whichever we release next.

All 32 comments

Curious: What browser+version are you using when you see this error? Any chance it's Chrome 49? Can you reproduce on Firefox or any other browser?

Also, can you provide a simple jsfiddle that demonstrates the issue?

@jimfb
Browser: chrome
Version: 46.0.2490.80

It also reproduces on firefox developer version 47.0a2 (2016-04-18)
image

It is a big application we have. I will try to create a small fiddle for reproducing.

+1, I also saw this annoying message output every time after adopting React v15.

I found that typeError can be removed by deleting onClick event in div and is able to reproduce every time.

<div ... onClick={ onClick }></div>

to

<div ... ></div>

It happened on Chrome 49.0 and Firefox 48 (it threw TypeError: target is null) and Safar 9.1i.

@rickychien @omerts If someone could try to produce a minimal repro / jsfiddle, that would be very helpful!

@rickychien @omerts Another question, are you guys using ReactRouter and/or Redux?

We're seeing the same issue and are using both ReactRouter and Redux.

"react": "15.0.1",
"react-dom": "15.0.1",
"react-redux": "4.4.1",
"react-router": "2.3.0",
"redux": "3.3.1",

We see this even if we switch back to React 0.14.8, so I don't think it is specific to React 15.

We can only reproduce the issue by switching pages via react-router Links, not using browser back/forward buttons, so it's possible this is actually a react-router issue. Removing the onClick listener on the button fixes the issue for us as well.

Weirdly, our application has tons of other buttons with onClick listeners which get removed on route change which do not cause this error, so I'm having trouble figuring out how to repro.

Posted a Codepen over in #6371

We are having this issue as well, both with 15 and 0.14.8 so I don't think its related to the newest release.

We started having this issue once we added a componentWillReceiveProps method to a stateful component. Once we removed this function, the error no longer occurs.

Our core dependencies are:

"react": "^15.0.1", 
"react-dom": "^15.0.1",
"react-redux": "^4.4.0",
"redux": "^3.3.1"

I trimmed it down to a case that involves just React.

Fiddle: https://jsfiddle.net/ycLw3bbq/

var callbacks = [];
function emitChange() {
  callbacks.forEach(c => c());
}

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { showChild: true };
  }
  componentDidMount() {
    this.setState({ showChild: false });
  }
  render() {
    return (
      <div>
        <ForceUpdatesOnChange />
        {this.state.showChild && <EmitsChangeOnUnmount />}
      </div>
    );
  }
}

class EmitsChangeOnUnmount extends React.Component {
  componentWillUnmount() {
    emitChange();
  }
  render() {
    return null;
  }
}

class ForceUpdatesOnChange extends React.Component {
  componentDidMount() {
    this.onChange = () => this.forceUpdate();
    this.onChange()
    callbacks.push(this.onChange);
  }
  componentWillUnmount() {
    callbacks = callbacks.filter(c => c !== this.onChange)
  }
  render() {
    return (
      <div key={Math.random()} onClick={function(){}} />
    )
  }
}

ReactDOM.render(<App />, document.getElementById('container'));

Also, a few observations:

  1. This only happens with onClick listeners which get queued here for Mobile Safari.
  2. It seems related to batching. In the initial reproduction cases, I still used a <Link>, and I noticed that navigating inside setTimeout instead didn鈥檛 repro the problem, but wrapping it in unstable_batchedUpdates did. In my small repro above, I don鈥檛 use events or unstable_batchedUpdates, but it seems like doing this stuff inside the initial render batch has the same effect, so I鈥檓 calling forceUpdate and setState in componentDidMount.

Replacing

  render() {
    return (
      <div key={Math.random()} onClick={function(){}} />
    )
  }

with

  render() {
    return (
      <img key={Math.random()} />
    )
  }

reproduces #6371 (Uncaught Invariant Violation: Must be mounted to trap events).

I guess the issue here is that all transaction.getReactMountReady().enqueue calls in mountComponent seem to imply that unmountComponent is guaranteed to happen after getReactMountReady() callbacks have happened, but this may break if one of those callbacks can cause children component to unmount.

I think the sequence is:

  1. Composite parent enqueues its componentDidMount in transaction.getReactMountReady()
  2. DOM component mounts
  3. DOM component enqueues DOM-related in transaction.getReactMountReady().enqueue
  4. transaction.getReactMountReady() starts calling its callbacks
  5. The composite鈥檚 componentDidMount was registered first, and it queues an update to the child which causes the DOM component to unmount
  6. DOM component unmounts
  7. transaction.getReactMountReady() proceeds and calls the unmounted DOM component鈥檚 callbacks

Yet another manifestation of the same issue (this time, only in master).

  render() {
    return (
      <input key={Math.random()} />
    )
  }

gives Uncaught TypeError: Cannot read property 'valueTracker' of null

I won鈥檛 be looking into this more for now as I鈥檓 not sure how to proceed.
I think @spicyj might have more context here.

This is a visualization of what happens.
Note how div(4)#reactMountReadyCallback happens after div(4)#unmount.

screen shot 2016-04-22 at 19 45 34

6371 was reported earlier and these two errors are caused by the same underlying problem so I propose to close this one in favor of #6371. @jimfb?

+1 I have the same error since i upgraded to 15

As per @gaearon, yes, this is a duplicate of #6371 so we'll close in favor of that.

Just upgraded from 0.14.7 to 15.0.2 to get the fix for #3762. I'm rendering to tbody and got "Invariant Violation: findComponentRoot(..., .0): Unable to find element. " when navigating with a React Router <Link>. After upgrading, I instead get this "Cannot read property 'addEventListener' of null" error.

I will see if I can create a test case, but wanted to note it here for the record, since it seems like the bugs are related.

I just landed a fix for this (#6650) which will be in 15.0.3 or 15.1.0, whichever we release next.

This may be useful:

broken

<figure className='clip-card' onClick={::this.onClick}>

broken

<figure className='clip-card' onClick={() => this.onClick()}>

doesn't throw but obviously doesn't do what I want :)

<figure className='clip-card' onClick={this.onClick}>

In my case I was using 15.0.1 and after moving some components around this started happening. I updated to 15.0.2 and it didn't help.

I was on Chrome 49 and just updated to 50, same behavior.

No need for additional repro cases now unless you confirm they're still broken in master (or in 15.0.3/15.1.0 when they come out).

@spicyj I'll give it a go, is it 15.0.3/15.1.0 tagged somehow on npm or should I just install the master branch ?

@kilianc master branch.

Easiest is to install from npm from

http://react.zpao.com/builds/master/latest/react.tgz
http://react.zpao.com/builds/master/latest/react-dom.tgz

because you can't use our github repo without building.

I can't reproduce anymore with both 15.0.2 and master. It must have been a race condition that doesn't happen anymore :(

@kilianc I believe this issue is fixed in master. Not sure why you're unable to repro on 15.0.2.

There was also a super similar issue that was only showing up on chrome 49, which vanishes when you upgrade to chrome 50. Chrome browsers auto-update at some point, so perhaps that was your issue.

Either way, glad it's resolved for you!

@jimfb indeed, I have never had this issue again

I also had this issue, using Chrome 50 and React 15.0.2, and it was not easy to track down. Like @rickychien, I could resolve it temporarily by removing the onClick handler.
What eventually solved the problem for me was to change the Component that contained the onClick from a stateless component to a class based component.

@schneck It will be solved with the next update.

rowClick(e){
e.preventDefault();
alert('row is clicked' );
console.log('row clicked');
}


{this.state.items.map(function(item, key){

           return (
           <tr key = {key} onClick={()=>{this.rowClick.bind(this)}}>

                  <td >{item.id}</td>                     
                  <td>{item.employeename}</td>
                  <td>{item.dateofbirth}</td>
                  <td>{item.gender}</td>
                  <td>{item.emailid}</td>
                  <td>{item.presentaddress}</td>
                  <td>{item.permentaddress}</td>                      
                  <td>{item.dateofjoining}</td>
                  <td>{item.department}</td>
                  <td>{item.jobtitile}</td>

              </tr>

            )

         })
         };
         </tbody><tbody>

{this.state.items.map(function(item, key){

           return (
           <tr key = {key} onClick={()=>{this.rowClick.bind(this)}}>

                  <td >{item.id}</td>                     
                  <td>{item.employeename}</td>
                  <td>{item.dateofbirth}</td>
                  <td>{item.gender}</td>
                  <td>{item.emailid}</td>
                  <td>{item.presentaddress}</td>
                  <td>{item.permentaddress}</td>                      
                  <td>{item.dateofjoining}</td>
                  <td>{item.department}</td>
                  <td>{item.jobtitile}</td>
                  {/* onCvxlick={()=>this.rowClick(item, key)} */}
              </tr>

            )

         })
         };
         </tbody>

am, not able to call function in table its giving error
Uncaught TypeError: Cannot read property 'rowClick' of undefined

Hey, @Rajesh-Hegde! This issue is closed, but I thought I'd take a quick stab. Checking the following line:

 {this.state.items.map(function(item, key){ 
  // ...

When using map, the value of this in the callback isn't the component. Try passing this in as the second argument of map to specify the scope of the callback:

 {this.state.items.map(function(item, key){ 
  // ...
}, this) // Here

Beyond that, it this doesn't appear to be an issue with React itself. We try to keep this issue board focused on issues with the React library itself.

Checkout the https://www.reactiflux.com/ chat community, where you might be able to get more rapid turn on troubleshooting. Good luck!

Was this page helpful?
0 / 5 - 0 ratings