Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Did not expect componentDidMount timer to start while render timer is still in progress for another instance #7349

Closed
BlockChange opened this issue Jul 25, 2016 · 47 comments · Fixed by #7548
Assignees

Comments

@BlockChange
Copy link

Not sure this should be filed as a bug, or if this is intended behaviour, in which case it would be more of a feature request, for something that we lost since the last few versions.

Which is more specific error logging.

Since the last few version this error shows up too many times, without any usable stack-trace:

There is an internal error in the React performance measurement code. Did not expect componentDidMount timer to start while render timer is still in progress for another instance.

This mainly occurs when a prop or state is not defined. This wouldn't be a big problem if I could stacktrace it, but in this case I cannot lead it back to any related component, I have to go off on what I changed last.

I do use redux and the stacktrace does go back to createStore and then connect, but this should not be related since this error shows up regardless of which element has an undefined property.

It is also often accompanied by:

Uncaught TypeError: Cannot read property '_currentElement' of null

How do I debug this error? Or are there plans to improve this?

@gaearon
Copy link
Collaborator

gaearon commented Jul 25, 2016

This is on my list, I’ll look at fixing it this week. To be clear, this warning itself is not valuable to you, you should look for an earlier error in your code instead. This is just a symptom; the root cause is as you described:

This mainly occurs when a prop or state is not defined.

An earlier error occurred in your app, so scroll the console up and look at the original error, not this warning, or Cannot read property '_currentElement' of null.

@gaearon gaearon self-assigned this Jul 25, 2016
@BlockChange
Copy link
Author

BlockChange commented Jul 25, 2016

@gaearon Scrolling back there is no related error being logged, but React does choke on it, which is both strange and annoying.

@gaearon
Copy link
Collaborator

gaearon commented Jul 25, 2016

This probably means you are using a Promise polyfill that swallows errors. Could that be the case?

@BlockChange
Copy link
Author

@gaearon, that might be possible, not sure how to fix that though, I do get occasional errors from bluebird that a promise is not returning anything, I still have to find a solution for that.

@hareeqi
Copy link

hareeqi commented Jul 26, 2016

  • I get the same exact warning when props/state not defined
  • I scroll up in the console and there is no related error so i can't pin point which prop/state is undefined
  • I am using bable polyfill for async/await
  • My silly workaround for this was to put console.error(err) in all my catch statements and now at least i know the name of the prop/state which is undefined.

@AdityaAthavale
Copy link

I got the same Error today. As soon as I subscribe to a reducer form 2 different components loaded simultaneously on screen and trying to access the same reducer it throws the error.

I am using Redux.

@BlockChange
Copy link
Author

@AdityaAthavale interesting, it crossed my mind that it was because of multiple dispatches at the same time, but through nothing of it. This might be one of the causes

@jwdomingo
Copy link

I just got this error while trying to implement dimensional charts using crossfilter.js. I believe one of my crossfilter operations is causing the choke..

import React from 'react';
import crossfilter from 'crossfilter';
import update from 'react-addons-update';

class DimensionalCharts extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      data: [],
      charts: [],
      filter: {},
      index: {},
      indexGroup: {},
      value: {},
      valueGroup: {},
      index2D: {},
      index2DGroup: {}
    };
  }

  componentWillMount() {
    const data = range(256).map((i) => [ i, randomGaussian() + 8 ]),
      filter = crossfilter(data),
      index = filter.dimension((d) => d[0]),
      indexGroup = index.group().reduceSum((d) => d[1]),
      value = filter.dimension((d) => d[1]),
      valueGroup = value.group().reduceSum((d) => d[1]),
      index2D = filter.dimension((d) => d),
      index2DGroup = index2D.group();

    this.setState({
      data, filter,
      index, indexGroup,
      value, valueGroup,
      index2D, index2DGroup
    });

    this.filterAll();
  }

  filterAll() {
    const { index, value, index2D } = this.state;

    [ index, value, index2D ].forEach((dim) => dim.filterAll());
  }

  redrawAll() {
    store.charts.forEach((chart) => chart.redraw());
  }

  addChart(chart) {
    const newState = update(this.state, {
      charts: { $push: [ chart ] }
    });

    this.setState(newState);
  }
}

@dwilt
Copy link

dwilt commented Jul 28, 2016

I just got this by having a faulty function import

@gaearon
Copy link
Collaborator

gaearon commented Jul 29, 2016

As I said above this warning has zero effect on your errors. I will remove it soon but for now it is absolutely irrelevant and you can ignore it.

If you don't see the real error, this is a problem with your setup. Adding another comment in this thread about the type of error that caused it will not help us. It will occur for any error, so there is no need to describe many different ways you could cause an error in JavaScript. This is not specific to React or Redux in any way.

What will help us is if you reproduce this warning without an error before it, and share that code. Trim down your project, publish the result and instructions to reproduce, and send a link here. Then I can take a look at why your error is being swallowed. But again, if errors are swallowed in your setup, us removing this warning won't fix your problem. Your errors will keep getting silently swallowed because there is something else hiding them, and we don't know why. So please only add new comments if you have a project showing how an error gets swallowed.

Thanks!

@dwilt
Copy link

dwilt commented Jul 29, 2016

@gaearon sorry for posting without more info. I posted it because I was getting this warning without an prior errors being thrown. The issue was that I was importing a function from another file, and then function had an artifact reference to a class it was once a part of. There were no errors thrown in the Xcode console. Here is a gist of trimmed down example of the code that did it: https://gist.github.com/dwilt/605aa6ca4257d8a9615979fdaa82f405

@mikeifomin
Copy link

mikeifomin commented Aug 1, 2016

Hi guys I had a similar error in a browser console. And due of some debugging I found uncatched exception in my componentWillMount/componentWillUnmount functions. That exception did not traced to the browser console.
When I wrapped my code with a try/catch black the message from react disappeared and the catch block execute with an error.

componentWillMount(){
  try {
     doSomeStuff()
  } catch (e) {
     console.error(e)
  }
}

So I guess you should try to wrap a code inside component's lifecycle functions with try/catch

UPD
all this stuff only for catch an error. not for prod use

@gaearon
Copy link
Collaborator

gaearon commented Aug 1, 2016

No, adding your own try/catch is not the recommended solution, it's working around the real problem (something swallows your exceptions). It would be great if you could share your project. I could take a look at why your exceptions are being swallowed.

@BlockChange
Copy link
Author

BlockChange commented Aug 1, 2016

@gaearon Can you explain what the error tries to describe? Even if it is not relevant for the original issue.

"Did not expect componentDidMount timer to start"

Who/which function/component did not expect it? Does every element get a timer? or is there a central timer that starts?

"while render timer is still in progress for another instance"

Which other instance? What does that other instance have to do with this instance?

Is the error wrongly outputted (a.ka. not the real error) because a previous error was swallowed, and if yes then why is it outputted or how?

These might be very specific questions to answer, but the fact is that people are coming here to solve this mysterious error, that only shows up in specific cases. ( the intended, but also unindended cases)

We have no way to distinguish between the so called real error and one that is caused by something else.

I think letting people post their specific circumstances here is more helpfull to get a grip on it, than saying that posting is useless or irrelevant. Or that it occurs for any error is simply not true.

@mikeifomin
Copy link

mikeifomin commented Aug 1, 2016

@gaearon of cause try/catch only for detecting a problem. It's was surprise for me that exceptions in these functions are not logged to console by default.

@gaearon
Copy link
Collaborator

gaearon commented Aug 1, 2016

Thanks for clarifying. But errors in these functions should be logged. There’s nothing special about React lifecycle methods from browser’s point of view. If they’re not, that’s a problem with your setup, not with React itself. If you share the project reproducing it, I can take a look at why this happens.

@gaearon
Copy link
Collaborator

gaearon commented Aug 1, 2016

@BlockChange

Can you explain what the error tries to describe? Even if it is not relevant for the original issue.

Sure.

Calls to lifecycle methods are instrumented with performance measurement calls in development.

For example, we start a timer, then call your componentDidMount on the next line, then stop the timer. The same happens for render() method. This lets us later calculate how much time was spent in each component for ReactPerf measurements.

Normally every onEndLifeCycleTimer call corresponds to onBeginLifeCycleTimer call.

To ensure this, onBeginLifeCycle sets a variable called currentTimerType, and onEndLifeCycleTimer sets it back to null. We make sure that we don’t forget to call onEndLifeCycleTimer for some edge case by emitting a warning if the “current timer” is set to something other than null when the timer starts.

My intention was to use this warning to prevent people forgetting to call onEnd... when working on React itself. So this is a safety measure. I also wanted to enable it in user code in case there is some pattern in which the timer gets messed up, which we should fix.

The one thing I missed is that if the app’s code throws during a lifecycle hook like componentDidMount, the “current” timer will not be reset, and the warning will appear as a false positive. I didn’t think it’s a big deal because I thought that you’d see the real error anyway just above this warning.

But apparently it is so common that errors get swallowed in React apps that people just don’t see the original error 😞 . I’m not sure why—this is why I’m asking people to share their examples. Maybe it’s a bad Promise polyfill, maybe it’s a catch block above setState that people don’t realize swallows exceptions. It’s hard to guess.

I’m currently busy with create-react-app and couldn’t dedicate enough time into looking into this yet, sorry!

@vinhlh
Copy link

vinhlh commented Aug 3, 2016

I have this error when accessing a prop from the constructor

  constructor() {
    super()

    const { show } = this.props
  }

removing them or moving these statements to componentWillMount will help

@gabriel-miranda
Copy link

gabriel-miranda commented Aug 3, 2016

@vinhlh you have to do

constructor(props) {
  super(props);
  const { show } = props;
}

@gaearon
Copy link
Collaborator

gaearon commented Aug 3, 2016

@vinhlh

Have you had a chance to read through my replies above? You’ll currently have this warning with any error in your code but you should see the real error alongside it. Is it not there? If not, please share a project reproducing this.

@mouhsinelonly
Copy link

mouhsinelonly commented Aug 8, 2016

i am facing the same problem in my app i ll try to find the code that caused it and publish it here.

Note: i am using redux too

@jdemangeon
Copy link

I had exactly the same error in my application. I noticed that I had simply forgotten a comma in the json returned by my promise. When I corrected my json, everything is back in order.

@helgefredheim
Copy link

@gaearon

This example reproduces the warning if ownProps.params on the line marked with ** is undefined. Does this help?

import { connect } from 'react-redux'; // 4.4.5
import React from 'react'; // 15.3.0

const MyComponent = ({ mail }) => {
    return (<div>
        <h1>{mail.title}</h1>
        <p>{mail.message}</p>
    </div>)
}

export function mapStateToProps(state, ownProps) {
    const id = ownProps.params.id; // **
    const mail = state.mails.filter((mail) => { return mail.id === id})[0];
    return {
        mail
    }
}

export const Container = connect(mapStateToProps)(MyComponent);​

(I originally posted this to a different issue, but I guess it should be posted here instead.)

@mouhsinelonly
Copy link

i noticed that i get this error whrn i print a props that is undefined inside a deep nested component . ecample.

render () {
const {name} = this.props

return (

{name}
)
}
}

but when i do this i dont get the error

render () {
const {name} = this.props

if (!name) return false

return (

{name}
)
}
}

@Thesephi
Copy link

I got this error without any accompanying errors, and tracing back led me to finding out it was because of a syntax error while binding a Class Function to an <a> tag's onClick attribute, like so:

class MyClass extends React.Component {

  doSomething() { }

  render() {
    return (
      <a onClick={doSomething}></a> // this was the culprit in my case
    )
  }

}

@joecarney
Copy link

I got this error and it was to do with missing props on a render. My bad. Very simple to debug and fix, but the actual error message itself threw me a bit and brought me here. Good to read the reasons why it occurs

@gaearon
Copy link
Collaborator

gaearon commented Aug 23, 2016

Does anyone have a project I could run that reliably reproduces this?

@fedevela
Copy link

this happened a lot to me, but it was intermittent and was able to get rid
of it, not sure how

On Tue, Aug 23, 2016 at 8:59 AM Dan Abramov notifications@github.com
wrote:

Does anyone have a project I could run that reliably reproduces this


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
#7349 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/APYA_TEPnUTIaW5sExz3mCbIiEv6CKsMks5qivzXgaJpZM4JUNda
.

gaearon added a commit that referenced this issue Aug 24, 2016
* Ensure lifecycle timers are stopped on errors

Fixes #7349

* Address review feedback and add an extra test
@gaearon
Copy link
Collaborator

gaearon commented Aug 24, 2016

Fixed via #7548. This will be out in the next release.

@mgcrea
Copy link

mgcrea commented Sep 15, 2016

I've encountered these errors as well after upgrading React on a big project. My main issue is that on first render (after page reload), when I have some error somewhere that will break the initial rendering (eg. undefined used prop), I only get this error and nothing more. Also it often leads to 100% CPU usage and I have to manually kill the chrome process to properly reload. It's a pain!

If I first reload to a working route and navigate to another route with a broken rendering I properly get both errors (this one + the actual one I'm interested in).

I would thought that it would be caught by my root render try/catch but it isn't. Does anyone has encountered the same error swallowing behavior?

const renderRootEl = (nextRoutes) => {
  if (__DEV__) {
    const RedBox = require('redbox-react').default; // eslint-disable-line global-require

    try {
      render(
        <HotLoaderContainer errorReporter={RedBox}>
          <Root store={store} routes={nextRoutes} />
        </HotLoaderContainer>,
        rootEl
      );
    } catch (err) {
      render(
        <RedBox error={err} />,
        rootEl
      );
    }
  } else {
    render(
      <Root store={store} routes={nextRoutes} />,
      rootEl
    );
  }
};

renderRootEl(routes);

@gaearon
Copy link
Collaborator

gaearon commented Sep 15, 2016

My main issue is that on first render (after page reload), when I have some error somewhere that will break the initial rendering (eg. undefined used prop), I only get this error and nothing more.

This is most likely not React's fault. Try to simplify your setup until you see what swallows the real error. It might be some library you are using, a silent Promise polyfill, a hot reloading tool, your own catch() in a Promise or catch {} in code, etc.

If you can demonstrate React swallowing an error, please file an issue with an example.

zpao pushed a commit that referenced this issue Sep 15, 2016
* Ensure lifecycle timers are stopped on errors

Fixes #7349

* Address review feedback and add an extra test

(cherry picked from commit a229cdb)
@RocKhalil
Copy link

@gaearon I'm also having the error Warning: There is an internal error in the React performance measurement code. Did not expect componentDidMount timer to start while componentWillMount timer is still in progress for another instance. when using react-native-swipeout package on iOS. It's working fine on Android but keeps crashing on iOS. I can't ignore this error since the whole app is stopping...

@gaearon
Copy link
Collaborator

gaearon commented Sep 19, 2016

This is fixed in React 15.3.2.

It's working fine on Android but keeps crashing on iOS. I can't ignore this error since the whole app is stopping

I believe I explained several times in this thread but let’s reiterate this once again. This warning is entirely unrelated to real errors. It cannot possibly cause your app to crash because it is a warning, not an error. It is not the reason your app crashes, but a consequence.

This warning used to fire after your app code (not React) throws an error. An error in your component used to get performance measurement code into an inconsistent state, causing this warning.

After React 15.3.2 you will not see this warning anymore. However that won’t solve errors in your application code which cause your app to crash. If for some reason you can’t see the real error, consider checking if your code swallows it in a try-catch somewhere, if some of your Babel plugins wrap your code in unexpected try-catches, if libraries you use wrap your code in try-catches, or if your Promise polyfill or native implementation swallows errors.

@RocKhalil
Copy link

@gaearon there was an error in the library, here's the thread.

@joetidee
Copy link

Hope you don't mind me asking, but this error appears in my application sporadically and is accompanied by an error that suggests that options of thing[0] is undefined. When I refresh the page the error does not appear (although as mentioned the error appears infrequently). This suggests that it is a timing issue, so could I ask if I need to and how to wait for thing to be populated?

var thing = this.props.dataThings.filter(function (obj) {
                    return obj._id == self.props.thingId;
                });

                var thingOptions = thing[0].options;

@gaearon
Copy link
Collaborator

gaearon commented Sep 24, 2016

var thingOptions = thing[0] ? thing[0].options : null;

?

@mcherz
Copy link

mcherz commented Oct 21, 2016

@gaearon Ran into this state, searched, found myself in this thread. In my case, the error was a result of a copy/paste transposition; passing a container state down into nested components as a prop works better when you don't just paste this.state.myProp and leave it like that :-\

In any case, the error was tricky to track down because it appeared BELOW the componentDidMount timer error--leading me to assume that it was a result of the timer error, not the cause of it.

The structure that threw this was, basically: A container with an initial state of previewOn, containing a stateless child component that passes prop previewOn to its own child (container's grandchild). The child component (middle layer) is completely stateless, and doesn't call getInitialState--so this.state is undefined. Everything seems to be working as intended, except for the error order (per the attached screenshot). Not a huge deal, but definitely made debugging harder.
screen shot 2016-10-21 at 1 59 14 pm

@gaearon
Copy link
Collaborator

gaearon commented Oct 23, 2016

As I mentioned above, this warning doesn't show up since React 15.3.2. Please update React.

@exogen
Copy link

exogen commented Apr 11, 2017

If anyone is still seeing this in new versions of React, during tests, with Jasmine, let me save you some debugging:

We were testing an HoC by creating a component to wrap in the test and calling Jasmine's done() callback in that component's componentWillReceiveProps. It turns out that done() will just start running other tests right away – it doesn't wait until the next tick of the event loop. So other components were being tested before the componentWillReceiveProps containing done() even exited. This is a shortcoming on Jasmine's part. setTimeout(done) will fix it (or use jasmine-promises).

@pimvanderheijden
Copy link

Using React 15.5.4 and still get this warning. It also appears in 15.4.1:

There is an internal error in the React performance measurement code. We did not expect componentWillUnmount timer to stop while no timer is still in progress for another instance. Please report this as a bug in React.

Should I send details?

@gaearon
Copy link
Collaborator

gaearon commented Apr 25, 2017

You might be getting it if your code throws somewhere (check your console). You might also be swallowing exceptions in your code, so you don't see the issue. Try "break on all exceptions" in debugger and see if you can find it.

If this is a legitimate false positive you could file an issue, but we likely won't fix it in 15 because that code is already removed from master, and we're working on the 16 release which diverged too much.

@pimvanderheijden
Copy link

Indeed. Cause was an error in my code in componentWillUnMount.

@gaearon
Copy link
Collaborator

gaearon commented Apr 30, 2017

Cool! If it doesn't get displayed in the console make sure you're not swallowing exceptions. It's generally bad if they go unnoticed.

@nahumzs
Copy link

nahumzs commented Jul 11, 2017

I know there are a lot of different ways that this error can occur, hope my case can help someone out there,

In my case the error is related when the ref callback return null after props change and the component has been unmounted read: https://stackoverflow.com/questions/38401879/react-losing-ref-values, I'm using the ref to calculate a position of an $element, and of course on null value everything will fail, the only thing that I had to do was to test if the element passed by the ref callback is not null, and that made this error disappears, though is hard to debug this kind of error when React throw an error for another different cause.

@MikitaReut
Copy link

I have the same error in my project which uses ReactArt. Stack trace points to these lines. Not sure, but seems that it can be caused by calling this.unmountChildren() inside componentWillUnmount.

@scazzy
Copy link

scazzy commented Aug 10, 2018

I been getting this error quite frequently now, whenever a component is removed/unmounted

@gaearon
Copy link
Collaborator

gaearon commented Aug 10, 2018

As I said in every other comment in this thread, this error is just a symptom of another, real error in your code, that is being swallowed by your code (for example due to incorrect Promise handling).

At this point I’d say the easiest way to fix it is to upgrade to React 16. React 16 is more error-resilient and will point out the real error earlier (which is in your code, not in React).

I’m going to lock this because there are no further actionable items for us here.

@facebook facebook locked as resolved and limited conversation to collaborators Aug 10, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.