Tracker crashing with react-data-meteor

Hi all,

I have a Meteor app using React with about a dozen components. I frequently get this error in the console when using react-data-meteor sources:

Uncaught TypeError: Cannot read property ‘val’ of undefined
Exception from Tracker recompute function:
TypeError: Cannot read property ‘_currentElement’ of null
at ReactCompositeComponentMixin._updateRenderedComponent (ReactCompositeComponent.js:559)
at ReactCompositeComponentMixin._performComponentUpdate (ReactCompositeComponent.js:544)
at ReactCompositeComponentMixin.updateComponent (ReactCompositeComponent.js:473)
at wrapper [as updateComponent] (ReactPerf.js:66)
at ReactCompositeComponentMixin.performUpdateIfNecessary (ReactCompositeComponent.js:421)
at Object.ReactReconciler.performUpdateIfNecessary (ReactReconciler:102)
at runBatchedUpdates (ReactUpdates.js:129)
at ReactReconcileTransaction.Mixin.perform (Transaction.js:136)
at ReactUpdatesFlushTransaction.Mixin.perform (Transaction.js:136)
at ReactUpdatesFlushTransaction.assign.perform (ReactUpdates.js:86)

Here is how to reproduce it:

  • Create a new meteor app and remove all of the files created automatically.

  • Create main.html:

<head>
	<title>My App</title>
</head>
<body>
	<div id="myapp"></div>
</body>
  • Create main.jsx

MyComponent = React.createClass({
mixins: [ReactMeteorData],

getMeteorData() {
return {
stuff: Stuff.findOne()
};
},

render() {
return Value is {this.data.stuff.val}
}
});

Stuff = new Mongo.Collection(‘stuff’);

if (Meteor.isClient) {
Meteor.startup(function () {
ReactDOM.render(,
document.getElementById(‘myapp’));
})
};

  • Insert any value into Mongo, i.e. via browser console:

Stuff.insert({val: ‘hello world’})

  • Startup Meteor. Once the page renders, keep hitting browser reload button until the error appears.

  • If you keep hitting reload, sometimes the error will go away but eventually come back in a very non-deterministic fashion.

  • Sometimes the app will stuck in this state and the error will not go away until you restart the whole meteor app.

  • This will not happen often on this very simple example project. However, if you have a more complex project, this problem manifests quickly and tends to crash the app.

I’m running Meteor 1.2.1 on OSX with the latest compatiable version of the packages.

The problem seems to be with Tracker crashing under quite low load. How can I debug this? Any ideas why this might be happening and how to fix it?

Many thanks in advance!

Telman

Are you shure your this.data.stuff is defined on first rendering? It depends on getMeteorData. Just try to trace your reactive source:

getMeteorData() {
  let suff = Suff.findOne();
  console.log(stuff);
  return {
    stuff: stuff || {}
  }
}
1 Like

@mrzafod - thank you for your reply. It is usually defined on the first rendering. My problem is that it’s not always working on subsequent renderings.

Basically, what troubles me is that there’s no guarantee that the page will work all the time. It does work most of the time, however sometimes when I navigate to the page with components sourcing from react-data-meteor they are simply broken and I have to reload the page to get them to work again.

Does anyone else experience the same issue? If it’s just me, then there’s probably something wrong with my Meteor installation and I can reinstall it.

I’m having some weird problems with the tracker too, which I’m trying to solve for the past couple hours.
The app fails at a different point every time and I get:
Exception from Tracker recompute function:
debug.js:41 TypeError: Cannot read property ‘_currentElement’ of null

Component 1 passes every element of the array through second component:

WebsitesComponent = React.createClass({
mixins:[ReactMeteorData],
getMeteorData(){
    var websitesFetch = (Websites.findOne());
    if(websitesFetch){
        return{
            popular:Websites.find({}, {sort:{upvotes:-1}}).fetch()
        }
    }
    else{
        return {};
    }

},
render(){
    if(this.data.popular){
        var arrayToSend = [];
        for(let element of this.data.popular){
            arrayToSend.push(<WebsiteRender sent={element}/>);
        }
        return arrayToSend;
    }
    else{
        return false;
    }
}
});

Second component:

WebsiteRender = React.createClass({
propTypes: {
    sent: React.PropTypes.object.isRequired
},
render(){
    if(this.props.sent){
        return(
            <li>{this.props.sent.title}</li>
        )
    }
    else{
        return false;
    }
}
});

Thats why a lot of fans try to use Redux or Alt where you can trace all the stack of your data changed. Meteor reactivity is nice but it is difficult to find the reason why expected data is unavailable.

2 Likes

I’ve looked at Redux thanks to @SkinnyGeek1010 advocacy - will definitely consider using this in the future.

For this particular case, it seems that react-data-meteor has a problem with invoking Tracker reliably.

I’ve just tried TrackerReact (https://atmospherejs.com/ultimatejs/tracker-react) and the results were MUCH better. @ice32, I suggest you try that as well.

However, react-data-meteor is the “official” way to get data into React, most likely other users experience the same issue.

@sashko - should I log a ticket on Github?

Many thanks to everyone!

1 Like

Thanks for the recommendation, I have tried using tracker react today, but nothing seems to help. I can’t even get this simplified version to work:

WebsitesComponent = React.createClass({
mixins:[ReactMeteorData],
getMeteorData(){
    let data = Websites.findOne();
    if(data){
        return{
            popular:data
        }
    }
    else{
        return {};
    }
},
render(){
    if(this.data.popular){
        return(
            <p>{this.data.popular}</p>
        )
    }
    else{
        return false;
    }
}
});

:laughing: It is not about Tracker

render() {
    let content = this.data.popular ? (<p>{this.data.popular}</p>)  : null
    return <div>{content}</div>
}

I wish it was that easy to fix…I’ve changed the code as you said, and I’m still getting the same error “Exception from Tracker recompute function”

I don’t think Tracker is causing the problem - I’ve used it plenty for scenarios like this, and never had any problem like this. Will try to reproduce your problem tomorrow when I’m back on my laptop.

Where is your subscriptions? Are you sure they’re even invoked before your find queries are executed?

Thank you for replying, I really appreciate any help. I have been subscribing through the router, but since you’ve asked I’ve moved the subscriptions to the component, just to be sure, but it doesn’t seem to help. I have managed to get it to work with just one db document(using findOne() ) but never with more than one. And there is only 5 or so documents in the whole collection.

getMeteorData(){
var handle = Meteor.subscribe("allWebsites");
    return{
        doneLoading:handle.ready(),
        popular:Websites.find().fetch()
    }
},
render() {
if(this.data.doneLoading){
    var arrayToSend = [];
    for(let element of this.data.popular){
        arrayToSend.push(<WebsiteRender sent={this.data.popular}/>);
    }
    return arrayToSend;
}

Exception from Tracker recompute function:
debug.js:41 TypeError: Cannot read property ‘_currentElement’ of null

I’m not experienced enough to guide you with this very much, but there is so many things I would structure differently to achieve what you’re doing.

try this:

getMeteorData() {
    let data = {},
        handle = Meteor.subscribe('allWebsites')

    data.popular = Websites.find().fetch()

    return data
},

render() {
    return (
        <div>
            {this.data.popular.map(website => <WebsiteRender key={website._id} sent={website}/>)}
        </div>
    )
}

I’ve done it like above a million times, and never had issues with Tracker, except ofc for unnecessary reruns of getMeteorData (which bugs the **** out of me) :smile:

I wonder how you’re even able to return an array of elements from a render function, as all my work in React has required me to wrap everything return from a render function in a parent-element. Then again, I’m a total noob with this stuff :wink:

hope this helps!

2 Likes

Wow, it finally seems to work! Seems you can’t be as big of a noob as I am :slight_smile: Guess I’ve been doing everything wrong…Thanks a lot!

1 Like

Happy it fixed your problem :smile: Merry christmas!