Closed nickredmark closed 3 years ago
Bump. Another case would be to run a method depending on @state
Tracker.autorun ->
console.log @state.foo
I believe this has something to do with react-template-helper
. I was trying to migrate from code taken from reactjs:react (which lets you do {{> Component}}
instead of {{> React component=Component}}
) to react-template-helper
when it broke. I was using the same react-runtime
in both cases.
@nicolamr, @meteorfan: are you also using react-template-helper
?
@froatsnook thanks for your answer. Unfortunately that's not the case. I did have react-template-helper installed, which I now removed since I'm not using blaze anymore. Yet the problem persists. @meteorfan is just another account of mine, sorry for the confusion.
So you are saying that it works in your case? I wasn't sure Tracker.autorun is even supposed to work inside of a react component.
I did more research and it's even more confusing. Tracker.autorun
works for me inside componentWillMount always when using {{> Component}}
(from reactjs:react) and sometimes when using {{> React component=Component}}
from react-template-helper. Maybe it has to do with how they're nested? I'll try to make a repro.
I hope to get it working with react-template-helper! I like using it in componentWillMount because it gives me control over when I want to update state.
Full componentDidMount
code:
componentDidMount() {
let p = this.props;
let computation;
let uploader = new Slingshot.Upload('audioUpload');
uploader.send(p.file, function (error, url) {
computation && computation.stop();
if (error) {
console.error(error);
} else {
console.log('done!');
}
});
computation = Tracker.autorun(() => {
console.log('upload progress =', uploader.progress());
this.setState({progress: Math.ceil((uploader.progress() || 0) * 100)},
() => {
Dispatcher.dispatch('FILE_UPLOAD_PROGRESS', {
id: p.id,
progress: this.state.progress
});
});
});
computation.onInvalidate(function () {
console.log('we invalidated');
});
computation.onStop(function () {
console.log('why did we stop?!');
});
}
And of course, when I initiate a file upload, right away in the console I see "we invalidated" followed by "why did we stop?!" and then a few seconds later, the file successfully finishes uploading.
This isn't terribly crucial for me, as I've temporarily instated a setInterval
function to update the progress every 500ms. But it would be great if someone from MDG could look into this.
Bump. Is there anyone for which this is not an issue?
Since no one's pinged anyone from MDG yet, I'll go ahead and use that card now.
I SUMMON.. @stubailo! ;) Sashko, can you speak to this at all? Is Tracker.autorun
not meant to be used within componentDidMount
for some reason?
FWIW, I am having this exact problem also.
Personally, I think this is a bug - you should be able to use it from then. As a workaround, you might be able to use setTimeout
:
componentDidMount() {
setTimeout(this.startComputation, 0);
},
startComputation() {
Tracker.autorun(...);
}
Let me know if this works - I haven't tried running the code. But we should fix this bug since running an autorun from componentDidMount is super reasonable. @yyx990803, we should put this on the radar since it will be a gotcha with many tracker-based React data loaders.
Thanks @stubailo - this caught me out for a couple of hours today! The solution you posted works perfectly.
@nathanwebb make sure you also stop the computation from componentWillUnmount
- otherwise you might end up with a memory leak.
Brilliant - thanks for the tip
On 3 March 2016 at 19:22, Sashko Stubailo notifications@github.com wrote:
@nathanwebb https://github.com/nathanwebb make sure you also stop the computation from componentWillUnmount - otherwise you might end up with a memory leak.
— Reply to this email directly or view it on GitHub https://github.com/meteor/react-packages/issues/99#issuecomment-191648907 .
@stubailo, thanks so much for the workaround. I spent a big chunk of yesterday trying to figure this one out. Works perfectly now!
Wow nasty one. Thanks for the circumvention.
@benjamn @stubailo as we experience similar issues with angular-meteor-auth
package and the initial Tracker.autorun
for Meteor.isLoggingIn
it would be great if you could look into this issue again. It would be a great help if there is a debug log for the computation for being able which function is actually responsible to stop the computation.
Is there anybody having an eye on this issue? On a large app with Meteor + Angular
this issue is driving you crazy. Having no reliability on a subscribe
or autorun
to run properly is breaking the magic of Meteor
. Any traceable debug information would be great. This issue was rising especially since the release of Meteor 1.3.x
.
Just wanted to say that I don't use Tracker.autorun inside of a component since I started using react-komposer, see https://github.com/kadirahq/react-komposer
Could someone explain to me why this workaround works? I'm calling Tracker.autorun
through a redux dispatcher, which should be asynchronous, so how does this initial call inside componentDidMount
affect the computation inside an async method?
Any news about this bug?
After much time has passed and more knowledge has been gained, it makes sense to NOT have any Meteor or reactive stuff inside the component, but rather do that in the container instead (created via createContainer
) and pass props into the React component.
It works very well
2018 and this is still not fixed wow
@lchangdev use withTracker
from react-meteor-data package
I assume I would get in the same problems when using Cursor.observeChanges
but I could not find any example of how to use withTracker
with observeChanges
.
I'm going to unsub since 3 years later I haven't been using meteor in a while. I'm happy using next.js + graphql + ooth for the accounts system.
In general, I use withTracker. But I have a special use case where I want to update some CSS without re-rendering, so I need to use Tracker.autorun inside the component.
The setTimeout
workaround works for me, so I'll use that for now.
UPDATE: I've found instances where setTimeout(this.startComputation, 0);
does not run reliably. I've increased the delay to 1000ms and it works, but this is not ideal. It seems that the difference between a reactive computation and non-reactive computation is the number of elements on _onInvalidateCallbacks
(one is non-reactive, three is reactive). As a workaround, I've found the following works:
this.autorunManager= null;
componentDidMount() {
setTimeout(this.startComputation, 10);
},
startComputation() {
this.autorunManager = Tracker.autorun(...);
if (this.autorunManager._onInvalidateCallbacks.length < 3) {
setTimeout(this.startComputation, 10);
}
}
I'm closing this just because it's too old. We can open new issues for items that are still valid.
Most of these items were solved already or replaced by new strategies (like hooks)
If in a react class I add
to the componentDidMount method, the autorun method runs only once, but not each time the "foo" variable gets updated. The very same two lines of code achieve the desired result if I add them inside of meteor.startup