Open williamrenwick opened 9 years ago
Hey there,
@Yomguithereal, correct me if I'm wrong, but I believe the delay you're seeing is a consequence of baobab's default behavior of batching multiple updates together and then asynchronously committing them and emitting an 'updated' event (which is what your react component would be listening to).
I think you should be able to call tree.commit()
to force the tree to update when you want it to. I would give that a try and see if it works.
Here's the documentation under the 'Updates' section which describes it more precisely:
A baobab tree can obviously be updated. However, one has to understand that the library won't do so, at least by default, synchronously.
Rather, the tree will stack and merge every update order you give it and will only commit them later on (note that you remain free to force a synchronous update of the tree through tree.commit()
or by tweaking the tree's options).
This enables the tree to perform efficient mutations and to be able to notify any relevant cursors that the data they are watching over has changed.
Hello @williamrenwick. @tnrich is quite right. In Boabab v1 (behavior has now changed in v2 and you should probably check it out because it might get simpler for your use case), writes are batched and solved asynchronously. You can circumvent this by doing either one of the following solutions:
tree.commit()
to force the updates to be flushed by the tree.syncwrite
option to true so that the tree is written synchronously (you'll be able to read your writes) but will keep its update asynchronous for perf reasons.asynchronous
option to false but you might experience perf issues then.@Yomguithereal @tnrich Thanks for the response, however as you can see from the code supplied above I've already included the commit()
method on my tree inside hpPostActions and I'm still experiencing a slight delay. Is there any other reason this might be, or is it just the run time taken for the action to set the state and for the cursors to be notified of said state change?
Whoops, sorry @williamrenwick, I didn't see the call to commit()
you had made. I guess there might be inherent asynchronicity between the update of the baobab tree, and the propagation of that update to the actual internal state of react components. Not sure why that would be exactly or if it is necessary to the system. I'm sure @Yomguithereal would know better than me.
I should read the whole thing once more. Let me check that.
Ok. @williamrenwick, components are bound to the tree's update events so this.state.posts
won't update in the scope of your componentDidMount
hook even if you commit changes synchronously. The 20ms thing is strange however. Is you app huge? Is your posts array containing a lot of elements?
What you could do if you wanted to access the updated data straight away would be to use the cursors created by the mixin (this.cursors.posts.get()) within the componentDidMount
hook as a workaround.
Any update here?
I'm currently experiencing an issue with my website where whenever I update the state inside
componentDidMound
and then want to access the updated state within the same component I have to implement asetTimeout
to allow for the state to update - it's usually only a period of 20ms but it's still inelegant and I'd like to know if it's just something I'm doing wrong?Let me give you an example, I have a set of div elements that I need to get the positions of from the browser once they've mounted, which I'm doing like so:
homepageListItems.js
hpPostActions
then pushes the returned objects into an array inside my state tree:hpPostActions.js
stateTree.js
However when it consoles
this.state.posts
insidecomponentDidMount
it just returns empty arrays unless wrapped in a timeout. Just FYI this has happened elsewhere in the application when I need to update the scroll position inside of my state tree when a particular component has mounted. Any pointers in how to do this better?