-
Notifications
You must be signed in to change notification settings - Fork 47k
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
What is meant within the README of create-subscription
by async limitations? Can it be clarified?
#13186
Comments
create-subscription
by async limitations?create-subscription
by async limitations? Can it be clarified?
The proceeding paragraphs explain what the limitations are:
What this means is that you might get some jank when processing subscription updates (since the main thread gets blocked) and if you're using Suspense the loading state might be rendered sooner than it would be otherwise.
In your case, the third pattern should suite your use case
You can always start using |
@aweary To be more clear my question is not does it de-opt, but what causes it to de-opt? I already read the README so I understand that it is limited and what the implications of this are. But I still do not understand what causes its limitations. Within the advanced Gist there are various comments like If I cannot understand what causes async de-opts I cannot write code which avoids this. Edit: I just saw the link to |
Hi 👋
Conceptually, React does work in two phases:
React organize work this way because it provides a couple of benefits:
In order for React to safely leverage these benefits it is important that components do not cause side effects during the render phase. This includes subscribing to something (e.g. adding an event handler). Adding a subscription should only be done in the commit phase ( How is all of this related to your question? 😄 Consider the following async rendering scenario:
create-subscription handles this possible case by checking if the value that was rendered is out of sync with the latest value and scheduling a new render by calling State updates scheduled from That might sound like a good thing, but what if the re-render includes a lot of components or is slow for some other reason? Then it might impact the frame rate and cause your application to feel unresponsive. This is what we are referring to when we say that create-subscription de-opts to synchronous rendering mode in some cases. |
To circle back to your initial point of confusion @sebinsua, I think the language in the README is just slightly confusing. With this section:
It's mainly referring to the other two, more common uses cases (external state store, low-frequency I/O subscriptions). If you opt to use that template you'll have more control over the subscription with the same async-safety. If you don't need that control you can just use
|
Excellent answers. Thanks a lot for your help! Edit: I'll sum up my own understanding for anybody reading:
|
I test the @bvaughn @gaearon IIRC, suspense/async render won't change the setState behavior in the commit lifecycle, e.g. before the setState is async, it won't be synchronous even on async/render. Test on local build react and
Hi, brian, I have a little question here. If so, we can't response to the transition of the data changing. E.g. the event dispatcher dispatch 'foo', and then dispatch 'bar', and then dispatch 'bar2', we can just receive the 'bar2' at the end(due to If I'am wrong, please let me know, thanks! By the way, what does 'de-opts' and 'de-opting' mean? |
I could be wrong, but I think what is meant by synchronous here, isn't what you are suggesting. I think the idea is that calling To quote @bvaughn:
It does not mean that immediately after calling
Presumably de-optimises (where the optimisation which is being lost is asynchronicity). |
Even in async mode, 'the state which you are updating with will be the state which is flushed to the screen' is still applicable. And I think the 'correctness' is only about asynchronous because synchronous is always correct. IMO, the 'synchronous' here which @bvaughn want to say is, the commit phase method will only be called once, no suspend, so we call it 'synchronous', by contrast, async render/suspense will suspend/yield the render phase method which would cause these methods be called than once maybe. so we call it 'asynchronous'.
Yea, I thinks so. So maybe we need adjust the description 'Calls to this.setState within the commit phase (e.g. componentDidMount, componentDidUpdate) are synchronous.' a little? |
|
@gaearon Thanks for your clarification dan! Just one question,IIRC, it seems it's not 'the top-level JavaScript call stack' but 'the |
I'm not sure what you mean. I'm saying that we don't exit the top level frame before committing. |
Thanks for clarifying Dan. My wording was a little misleading I guess. State updates from Here is an example: class Example extends React.Component {
state = {
count: 0
};
componentDidMount() {
// Don't actually do this!
this.setState({ count: 1 });
}
componentDidUpdate(prevProps, prevState) {
if (this.state.count === 2 && prevState.count === 1) {
// Don't actually do this!
this.setState({ count: 3 });
}
}
render() {
return <div>count: {this.state.count}</div>;
}
} The above component will render count 0 and 2, but a user would never actually see those counts– only 1 and 3, because of the |
@gaearon Sorry, my fault, I mistakenly treat the word 'top' as 'bottom'. Our understanding is identical. @bvaughn Yea, that's how batch update works. But I think this is irrelative with create-subscription or async/render or this thread because even in react@15, it already has batch update and async render is about fiber, chunk, time-slicing, expriationTime ... By the way, could you please answer the second question in my comment above? Thanks! |
I'm confused by your most recent comment, @NE-SmallTown. My example above doesn't really have anything to do with batch rendering (as there's only ever one state update in the queue at a time). I was just trying to clarify about how state updates are handled during the "commit" phase. Not sure I know what second question you're referring to. |
Yes, there is no multiple update at a time. My wrong description. I will try to describe my thoughts more clear. I'm very very sorry about wasting your time !
Sorry for the ambiguous, you can try command + f to search the key 'I have a little question here' on this page. |
I'm having a little trouble understanding what you're asking, sorry. All I am saying, essentially, is this: Calling As someone pointed out above, React does not update |
@bvaughn I think you mean |
Yikes! Thanks |
What's the meaning of "de-opting"?
|
@towry In the context you're referring to, it just means that React can't continue rendering asynchronously (which is ideal). In some cases with |
What is meant within the
README.md
ofcreate-subscription
by async limitations?The patterns described above are:
I don't think any of these suit our use case: a high performance WebSocket stream that produces price quotes which are rendered directly into components. The application domain is a realtime trading application for an investment bank I am consulting for.
Ideally, we want the price quotes to be passed straight into the component with as little ceremony as possible. This state will be transient, so:
react#Context
and to then pass the data down the tree, since I can just import the service wherever I want in my code and pass callbacks into this to begin receiving data. The latter seems simpler, with less ceremony and will make it easier to differentiate between different streams of price updates.It seems to me that
create-subscription
is exactly what I need, however the comment about async limitations worries me. Is there something I'm missing? Could this be clarified in the README?Is it because of priority? I think ideally we wish the price updates to be treated as if they are high priority, because we would prefer to decrease the likelihood of clients interacting with stale data.
The text was updated successfully, but these errors were encountered: