4 ms·
The React team has been pretty clear that Concurrent Mode needs rendering to be pure, as render methods may get called multiple times but have the results throw
by acemarke 7y ago
The React team has been pretty clear that Concurrent Mode needs rendering to be pure, as render methods may get called multiple times but have the results thrown away if the render pass isn't completed and committed to the DOM.
The case of user input is particularly relevant here.
Say React starts a render pass for a relatively low-priority update. It walks through the component tree asking components to render themselves, runs out of time on this tick, and pauses the half-calculated render pass. While paused, the user types a key in a text input or clicks a button. That will be treated as a much higher priority update, so React sets aside the half-calculated render tree, does the complete render pass based on the input event, and commits it to the DOM. It can then "rebase" the half-completed low-pri render pass on top of the new tree that resulted from the input update.
If components go kicking off side effects while rendering, whether it be as simple as mutating a React ref object or more complex like an async request, those side effects will likely result in unwanted behavior because they might happen multiple times or happen at the wrong time.
- lhorie 7y agoYes, I'm aware of the concurrent mode contract. But do you see the Stockholm syndrome here? If I were to tell you that in order to use a hypothetical Floober framework, your code must be tail call optimizable or else the framework has undefined behavior, surely you would think the author of Floober framework was insane. It seems strange, for example, to dismiss async functions on grounds of function coloring when the alternative is coloring functions with a conceptual requirement of "purity". Or to ignore the opportunity for a paradigm shift to something more naturally reactive (e.g. a la s.js) considering how there was already an API shift when going from OOP components to functional + hooks.
- bikeshaving 7y agoYou’ll notice that in a lot of the Crank examples, I freely mix side-effects with the actual yielding/returning of elements. This is because Crank doesn’t treat side-effects as special. Given that rendering is a huge side-effect in and of itself, I always thought is was kind of unfair that React could peform them and the user couldn’t. The reason this is possible is because Crank is executionally transparent. If you render a component, and that component calls refresh 4 times, the developer can know that the component has been updated 5 times. You get no such guarantees with React, and it will even go out of its way to make sure that you don’t put side-effects in your code by calling your components multiple times in development, which I think is crazy.