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

Why is 'onInvalidate' only called once (in observeUntilInvalid) #21

Closed
mehdi-cit opened this issue Aug 21, 2015 · 2 comments
Closed

Why is 'onInvalidate' only called once (in observeUntilInvalid) #21

mehdi-cit opened this issue Aug 21, 2015 · 2 comments

Comments

@mehdi-cit
Copy link

Hello,
I'm trying to see how to use mobservable to 'intelligently' and efficiently listen to state changes and identified observeUntilInvalid as a plosible 'candidate' to use.
observeUntilInvalid( functionToObserve, onInvalidate )
when it "evaluates" that 'functionToObserve' has a different 'outcome' it runs onInvalidate. However, this only happens once!!! subsequent changes to state that would lead to a different outcome of functionToObserve no longer cause onInvalidate to be ran.
Why is that? Any clues on how to achieve the above scenario?
https://github.com/mweststrate/mobservable/blob/master/docs/api.md#observeuntilinvalidfunctiontoobserve-oninvalidate

PS:
I can see starting line 813 //mobservable.reactiveMixin
it's indeed using observeUntilInvalid within componentWillMount.
But how would that work if componentWillMount is only run when the component is mounted (At least that's implied by its name). It (the 'onInvalidate' function that causes update => '_this.forceUpdate()') won't be re-run when state changes. I must be missing something.

@mweststrate
Copy link
Member

Hi,

observeUntilInvalid is a function you will rarely use, exactly because it run only once. Generally speaking you need sideEffect to observe something.

observeUntilInvalid in the react mixin will take the output of the observed function (which is the components render function) and return it as rendering to react. But in the mean time it tracks the dependencies and waits until the function output becomes stale. Then, it doesn't recompute, but instead call reacts component.forceUpdate and dispose itself.

reacts forceUpdate function will trigger render again to update the component, and render will trigger observeUntilInvalid, so it basically 'loops' again. The reason forceUpdate is used instead of just re-evaluating render, is that invoking render directly in itself doesn't do anything. Sure, it generates some output, but its output should be injected in the lifecyce of react components, otherwise it doesn't do anything.

So instead of re-evaluating the render method, we invoke forceUpdate, which is the proper way to trigger a render in react.

These are a lot of words, I guess an image would do better ;). Just let me know if it is still unclear

@mehdi-cit
Copy link
Author

Thx, this helps a lot!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants