As an outsider, I honestly feel that there's a strong difference in opinions between Dan and Sebastian. One doesn't need to reason too hard about the purity thing: Dan himself admits hooks were criticized (accurately) for being impure.
On the other end of the discussion, the claim about impurity preventing prioritization is very weird, because simply going async will shuffle the rest of your rendering further out in the microtask queue, giving the opportunity for event handlers to fire half way through a vdom render pass, effectively prioritizing user input.
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.
Yes, 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.
You’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.
The whole React story is very interesting. Authors are extremely adamant about everything being pure, but React still doesn't solve an underlying issue that every frontend framework since the beginning of time solved. Which is automatic tracking of properties and re rendering efficiently(think Vue, Angular, Angular 2, Ember). IMO you need all these new optimization techniques crammed on top because it's so easy to shoot yourself in the foot with performance out of the box with React
Oh you didn't memoize a function, well you just re rendered a FlatList with 500 items in it on an Android phone that cost $0. You need an addon library such as Mobx to really unlock the power of React and make it sane enough to use.
Yes, for sure you can get good performance out of the box. It just takes a lot more time than other frameworks. In my experience it's a constant moving state up and down. Spending an insane amount of time to put state in the correct spot so it will be efficient. The easiest thing is to just put all state/business logic in domain objects and subscribe the components to it. That's how you're used to thinking about business logic of an application anyway. It's easier to reason about and it performs much better. This whole useMemo, useCallback, is just comical. Let the computer do the work for you.
Weird, never had any of those issues. I've always had state near the top and used props to bring it down. Pure components (which is any function component) do not re-render unless their props change. I've built rather complex applications also in the logistics and financial forecasting verticals. We are talking many tables, charts, dashboards, etc...
In fact, I found the MobX approach with reactivity harder to control performance for because it's triggered by state changes. But when you trigger a lot of state updates it can be really hard to reason about performance because it's not obvious what components will update due to that change in state.
Tables, Charts and Dashboards sounds like a lot of displaying of data. Not updating state. Or when you are updating state (like date picker), you're updating the world. Just an assumption, sorry if I'm wrong. Web is usually fine to be honest, doesn't come up until you're pushing state on keypress. The Stripe onboarding page and Twitter create tweet UI both have these performance problems. My day to day is React Native which is where these problems crop up almost immediately and getting performance out of the box is a chore that, again, none of the other frameworks make you do. Computers are smart they can solve these problems for us.
On the other end of the discussion, the claim about impurity preventing prioritization is very weird, because simply going async will shuffle the rest of your rendering further out in the microtask queue, giving the opportunity for event handlers to fire half way through a vdom render pass, effectively prioritizing user input.