I’m sorry but this is not a fairly complex app. When things do get more complex (and not even that much) is when you start hitting problems. How would you reuse a “component”? Among many other things.
I honestly don’t know if that’s the point of the author but I would agree that many framework are too heavy, but honestly there so many good compromises today that don’t make you re-invent the wheel and fix bugs that have been have been fixed millions of times before.
Going against good abstractions as developers seems to go against the most powerful tool we’ve got.
It's a good way for people to revisit the current status quo and avoiding cargo cult. Frameworks are useful, but there's definitely an element of cargo cutting going on in the JS ecosystem whereby no matter what the requirements, you just reach for React/Vue. We're getting to a point where almost nothing that uses JS gets built without a frontend framework (and all its weight) anymore.
One thing that's easy to notice from reading the code is that so much of the code takes inspiration from the frameworks themselves. How the code is organised - the state store, the render function, the computed getters, the mutation methods, it's all there. It's clean.
Perhaps the main benefit of frameworks is that they've taught a whole generation of JS developers how to organise their code in a way that can scale to bigger, more complex apps (vs. how easy to make a mess of things in the jQuery days).
-
Having said that, I do agree with your point about things getting more complex: This is a properly specced, easy to grasp project. Throw in stakeholders and PMs needing to add functionality and requirements changing, and this system might start to struggle. Not to mention the cost of onboarding new developers. I feel like that's the best thing about frameworks in any language; when you jump into a new project you know more or less how everything is organised and where things are supposed to be, and you can get going fairly quickly.
Building on your comment, frameworks have described themselves as “polyfills”. Polyfills used to be libraries that added modern browser features to old browsers. Then, Angular and React began using polyfills to add future features to modern browsers. The intent was always communicated as “some day we won’t need this because it’s built in to HTML5 and when that happens your initial payload will be smaller”. Typescript has had similar effect on JavaScript language features and syntax.
This rewrite of the Vanilla JS TodoMVC is a great illustration of how far things have come.
Save the element template as a string and set innerhtml of a div as that?
> compromises today that don’t make you re-invent the wheel
Yeah but there's also no need to include jQuery and bog down your site with piles of code you won't ever call just because you don't know how to use the native api like a normal person. React/Angular/whatever are just the latest fad of that mindset, big team corporate ease of use aside.
What happens when you need to update some deeply nested child element without re-rendering the whole tree? Suddenly you need some system of labeling the children, how to find them in the dom, how to update them, how to keep them in sync with the state... a vanilla JS solution becomes extremely unwieldy as soon as you step out of the "global pointers to elements" phase (what the project in the OP is). Lit-html is an example of a tool that solves this problem in tiny package- less than 1KB- and you can continue using string templates with that.
I mean speaking for myself, I mostly make robotics web apps which isn't the most typical of web applications but the times this sort of thing is needed are few and far between.
So yes, this pattern is helpful for solving that sort of thing when it occurs (and if the use case is even substantial enough to warrant it) and Lit looks like it would fit that role reasonably well, but basing the entire site on this principle as a full on framework seems a bit ludicrous.
What html actually lacks is the option to include external html part files, but there are lots of ways to do that serverside that don't involve the stupid idea of putting html into strings in js files for literally everything.
While I would rather nail my bollocks to the ceiling than build a vanilla application (in any stack), there’s no denying the benefit revisiting the basics.
Yeah, that's exactly what I would imagine vanilla js code look like, and I'm glad we moved on to frameworks. Just this small app seems not so fun to maintain
Yep, it’s a really nice demo for how to use JavaScript. But it’s not a valid criticism of Vue, React, Svelte because it’s solving a very simple problem. The reason for those frameworks becomes clear when you have multiple people maintaining it and adding features.
The code here is clean, well written and honestly not that much more verbose than many of the framework ones. I also found it simple to understand.
Would you need a “framework” when an app gets beyond TODO? I think you would need to start refactoring your code to be more framwork-like. But this is something we don’t do, and I would say would even be considered “anti-pattern”.
My bet is that as soon as someone popularizes a way to manage state across a set of web components the pendulum will swing back to the “Vanilla JS” approach. It’s so nice to work on web apps without having to install NodeJS, builders, cli tools, and so on. And it encourages software engineers to learn the web platform APIs instead of learning frameworks.
HTML and CSS are actually quite nice to work with, given modern browser developer tools. Much simpler to work with when they are literal files.
It wouldn’t surprise me if people continue to compile other languages to JavaScript or WASM though. It seems reasonable a Java developer might like to work in Java or a Ruby developer in Ruby instead of writing JavaScript. But I don’t understand how people feel confident writing web applications if they don’t take the time to understand CSS, HTML, or the browser APIs.
The thing I enjoy about frameworks like React is the declarative nature of the UIs.
I'd love to not be able to use them and to create complex UIs in pure JavaScript but it always ends up being painful where you spend more time optimising the rendering than doing any work.
In simple apps I will write UI in a functional matter in pure JavaScript, regardless of the performance implications. But bigger DOM means worse performance with this method.
When will we get to the point where we can tell the browser what we want the DOM to look like and then the browser does the diffing like a framework would?
i agree it's up to the browsers chromium , Safari , and Firefox to do the diff. But we might need a new meta tag or change to the Fetch API to tell them this html page should only update the elements that are different.
> If you're developing a single page react app, I don't think you care about the back button.
You should though. One easy way is to use react-router. e.g. going to /profile renders the Profile component. Then navigating to /dashboard renders the Dashboard component. Pressing the back button will take you to /profile.
Another pet peeve of mine is people using internal react state when they should just use path or query params to make it transparent and easily sharable.
Echoes of Alan Kay's recent comment on how software devs are way too concerned with the how the computer works to the detriment of what the software is supposed to do.
I agree. In over 20 years I've never had a single user ask or complain about the size of the app. They have let me know when there was something not working right though.
There's sort of a "Maslow's Hierarchy of User Needs" that exists in software though. So long as the user can do something, and their immediate needs are met, performance concerns are just a small annoyance. And generally they will continue to ask for more features rather than performance improvements as long as the app remains usable.
Well then you've never seen poor people uninstalling apps from their cheap smartphones because they need to install and use a different one ;-) that you don't see it doesn't mean it's not there
Yup. The reality is that programmer time is far far more expensive than compute time. And as long as that's the case, increasing levels of abstraction are our only hope at building complex software.
Programmer time is more important than their computer time, sure. Not sure that programmer time is always more expensive than the compute time of all the users of the software added up.
Yep because software devs is in the business of making money, while Alan Kay is in the business of smugly commenting from the side lines. He has very little understanding on what matters in the commercial world of software.
it sounds sort of wild to expect there to be diffing! why do you have to generate a whole copy of the stuff instead of just telling the browser what changes to make? bonus: the existing apis instead of one that don't exist yet.
Diffing seems necessary when your UI gets complicated to the level that a small change requires a full page re-render. However, I don't think this is necessary for at least 95% of the websites on the internet.
Diffing is exactly what you need to do (barring newer methods like svelte) to figure out what to tell the browser to change. The vdom tree is much faster to manipulate than DOM nodes.
But you can't see those changes until the actual DOM changes as well. It's only because of react's insistence that mutation is evil that this became a problem. You could just directly update the thing you wanted to and just skip the whole diff thing.
No, the reason React has a VDOM is because the DOM is slow to update, compared to manipulating javascript objects. It's worthwhile to calculate the list of minimum updates ahead of time rather than using the DOM as the source of truth.
Not sure where you think mutation comes into play here, that's an orthogonal concern—you can have an API that mutates some internal representation of a VDOM, and it's still faster than manipulating the DOM directly.
In order to achieve immutability, large chunks of state have to be cloned whenever a single value changes. This sometimes causes a whole new DOM node to be created during reconciliation. React encourages you not to think about it too much. But some nodes can't be replaced. Like canvas or anything contentEditable. It's not orthogonal. It's a direct consequence of the design philosophy.
Because it can be automated? Every app that doesn't do this is just implementing the diff by hand, e.g. on this event delete this element, update this element, add CSS class to this element, etc. When the UI gets complicated you have to maintain this all yourself and it's a pain. Multiple event listeners between components to say something has happened.
It makes sense to be able to describe what you want to achieve and to let the browser determine how to get there in the most efficient way.
If the browser could do this it would make a tonne of JS code so much simpler. There's a lot that goes into making sure that there's no unnecessary DOM updates because it's just slow.
I don't write assembly and move things between registers by hand, I write a function and the compiler decides the most efficient way of doing it. UI should be the same way, I say what I want to happen and the browser decides how to get there.
Yes... but that's the exact argument I'm making here. Unless you want to go through that pain, you need a framework.
Whether that's Svelte without a VDOM or React with a VDOM. The entire point of these frameworks is that you can write complex UI in a declarative way. They both exist because writing it declaratively in pure JS leads to performance issues. But there's nothing stopping the browser implementing something that does this optimisation for you.
I mean, it’s clear that with a single view, it’s possible to manage this without too much trouble. But next to no apps are single views. And any project that has multiple people working on it is going to have multiple views and features which all interact in interesting ways. It’s definitely not overstated. Try writing a moderately involved app yourself in plain JS! It does get to be a pain, I’ve done it! By the time you finish, you’ll have likely created some level of abstractions, and invented yourself a nice new JS framework for yourself ;)
Yes, but there are ways to accomplish this automation without diffing. Svelte does this by statically wiring up the data dependencies in your app when it builds, and then at runtime making exactly the changes to the DOM that it needs to based on the information it had at build time. No need to diff.
The point is that A) that's a framework and B) that requires you to compile Svelte files.
If you want to write declarative UI in pure JS then you need the browser to do these DOM optimisations for you, and diffing the changes is the way to do that.
There’s absolutely no way you’ll have worse performance with this vs React. The app is modifying the target elements directly, not recreating the whole page with innerHTML. React will do the same amount of work at a minimum, and that’s after rebuilding the whole tree and diffing it.
The main bottleneck here are the synchronous localStorage calls happening in the render path, they could be moved to a separate timer.
The rendering code here is already batched since everything happens within a single render() call. And unless you’re using react fiber, its rendering is also synchronous.
I did this style to mimick modern framework code — taking the state (todos) and render the state of the world every time. If the browser had a DOM diffing api this would be more efficient and we would be there. So for a larger project I might using something like Lit’s html stand-alone package or fastdom to get the DOM digging functionality without much dependency code.
> There’s absolutely no way you’ll have worse performance with this vs React.
It's normal to get much worse performance than React if you layout thrash and it's very easy to layout thrash without batched updates. There's overhead in the vdom but getting all the updates batched tends to be a performance win in any decent sized app. This was an active area of library exploration/development in the 2008-2012 timeframe but the only framework actively promoting it was Sencha IIRC.
Cases where "UI should be a function of state" seem like a small sliver of all use cases. Probably not worth the complexity for implementing directly in the browser. And there are plenty of conditions that just prohibit the pattern entirely as far as I can tell. Things where referential stability matters, like you have a contentEditable or allow arbitrary edits on a canvas.
Personally I would argue that UI should always be a function of state. When it isn’t, you open yourself up to all sorts of inconsistencies and difficult edge cases. Of course, it’s not always that easy; having two sources for said UI (the HTML document itself and the JavaScript within it) certainly complicates matters.
For what it’s worth, even using “vanilla” JS it’s generally much easier than it’s made out to be. It requires design discipline and knowing ahead of time what discipline to apply. But it’s pretty simple once you know it:
- the UI isn’t a source of truth, it’s a computed interface to it
- changes/interactions in the UI should update the source of truth, not other parts of the UI
- the source of truth is fully responsible for managing and notifying dependencies of relevant changes
Or much shorter: state and presentation are separate concerns. Once you have that, you can focus on the actual problems you’re trying to solve rather than the ones created by crossing underlying technology boundaries.
> Cases where "UI should be a function of state" seem like a small sliver of all use cases.
Maybe not “should”, but it’s an incredibly helpful mental model, and I can think of very few cases it can’t model correctly. It’s so helpful a model that it’s gained traction in Rust, Swift, Kotlin, Dart, Go. It’s the ~only model in Clojure and and literally the foundation of Elm.
None of these cases, AFAIK, apply the model literally when they interface with inherently imperative APIs. They provide APIs expressing the model, and manage the imperative behavior on your behalf. This is ultimately how all functions in meaningful programming work. At the end of the day, allocating memory or displaying output is a side effect.
This is also how you can have custom renderers like those used in ink, three-solid, even React Native. The code is modeled as a declarative function of state, implemented as a set of imperative behaviors corresponding to state and dependency changes.
I’ve worked on contentEditable solutions in the past, probably more than most people who didn’t ultimately produce a library from the work (I went mad, literally angry at the complexity of making it a good UX, and gave up). I hope I never have that task again, but if I do… you can bet your ass I’d use a function of state model. It’s the only way I could reason about the problem without going mad.
That’s a misunderstanding of MVC - it’s a design pattern that’s language agnostic, not a declaration that HTML needs to live separately from JavaScript. The view logic in JS lives separately from the model logic in JS lives separately from controller etc.
Looks well made, code is pretty good, but why the archaic form of JavaScript other than the import statements? There's a lot of well supported syntactic sugar that would make it much easier on the eye. I also wouldn't bother with the IIFE.
For me, the biggest issue with using vanilla JS is the lack of guardrails.
Before even considering something like this I’d want to see a style guide and clear definition of where code should live. Frameworks like React do that well. I can expect a random React dev to mostly do similar things.
> I can expect a random React dev to mostly do similar things.
This has not been my experience. Even experienced software devs will differ stylistically, but intermediate devs often come up with very different ideas about how things ought to work. I suspect this is due to wide variance in awareness of different libraries/platform features/stylistic patterns/etc, a consequence of being in a relatively unregulated industry.
I have worked for companies using React since 2014 and no 2 projects have had the same layout. My current and previous employers have had the closest codebases, but only in terms of directory structure, and even now the current one is changing to become quite different (in a way I think is good, but only time will tell).
My app CardBoard (https://www.cardboard.team/) is no-framework vanilla js. This is a large-ish codebase with a lot of functionality, and the same code is wrapped with apache cordova for both iOS and Android apps. In 2022, browser-native WebComponents (addresses encapsulation, code organization, and re-use) with no frameworks is a hill I'd die on.
How do we get 31 comments but not a single one on why this solution is subpar?
The entire TODO list is rendered anytime a single item is changed/removed/added. The biggest thing frameworks give us is fast, differential DOM updates.
Once browsers add differential update APIs, then we can kiss React and all the other players goodbye :-)
I mean... You aren't wrong, but the amount of data that fits on a typical page is usually such that the speed of a full refresh probably shouldn't be that big of a deal.
I wrote a TodoMVC App with React, Redux and SSR that works without JS enabled in the browser a while back, for those interested in that sort of thing :)
Thanks for sharing this. I have to admit, this is an absurd amount of code for a todo app. Is there a specific goal you had in mind when creating this? Are you trying to show the capabilities of SSR (or maybe Redux)?
The assignment (=) is missing from those const declarations, except for the first one; I guess they were hastily converted from function declarations to satisfy modern tastes.
Oh, hey! This is from the founder of Frontend Masters – easily the best FE resource I've ever found: https://frontendmasters.com/. Their content creation process is pretty nifty: they run live workshops regularly that subscribers can join, and the footage from the workshops ultimately gets cut and turned into the tutorials.
Had no idea who was behind it, but I love that they're still contributing back like this.
Ah, thanks for the plug!! I did this as a fun little weekend project, glad people are finding it useful as a reference of how simple vanilla JS can be these days. :-)
Nice! I was going to suggest the usage of Trusted Types API [0] to escape HTML [1], but support [2] for modern browsers is not there yet, specifically for HTML.
This code reminds me of Backbone. I think we all started here and then abstracted event handling and reactivity into a tiny framework like Backbone.
React and other declarative approaches are inherently different. In React I hardly think of when my component renders. In Backbone days, I remember having to debug why some part of code is not running when I'm expecting it to run. React does this really well.
A cool thing about react is that it’s easy to reason about as well. The reconciliation algorithm is fundamentally pretty simple and there isn’t any magic happening.
It can get confusing to track down unexpected renders when you think the result of the algorithm should be different, but that’s not really an issue with react so much a the nature of managing complex state, memoization algorithms which potentially use different diffing strategies, and logic which might be mutating state in ways you don’t quite expect, and so on.
People criticize these front end libraries but I’m still impressed by how well state management has been integrated into such extensible and scalable view layers.
I think there's a reason why events are not mentioned in your linked document... The reference is maintained in memory because the browser has no idea if you will be using it again. After creating the listener, you may very well append it to another element later for all the browser knows.
Also the browser doesn't make a distinction to the type of event (such as `click` ), and say "Oh well you can't click on an element not in the DOM, I think I can clean this up"
So no it will not clean it up and it will leak memory, see for yourself
Please do not re-implement HTML sanitization. Just replace that escapeForHTML and innerHTML assignment with a later textContent assignment. Please. Pretty please.
114 comments
[ 2.7 ms ] story [ 186 ms ] threadI honestly don’t know if that’s the point of the author but I would agree that many framework are too heavy, but honestly there so many good compromises today that don’t make you re-invent the wheel and fix bugs that have been have been fixed millions of times before.
Going against good abstractions as developers seems to go against the most powerful tool we’ve got.
One thing that's easy to notice from reading the code is that so much of the code takes inspiration from the frameworks themselves. How the code is organised - the state store, the render function, the computed getters, the mutation methods, it's all there. It's clean.
Perhaps the main benefit of frameworks is that they've taught a whole generation of JS developers how to organise their code in a way that can scale to bigger, more complex apps (vs. how easy to make a mess of things in the jQuery days).
-
Having said that, I do agree with your point about things getting more complex: This is a properly specced, easy to grasp project. Throw in stakeholders and PMs needing to add functionality and requirements changing, and this system might start to struggle. Not to mention the cost of onboarding new developers. I feel like that's the best thing about frameworks in any language; when you jump into a new project you know more or less how everything is organised and where things are supposed to be, and you can get going fairly quickly.
This rewrite of the Vanilla JS TodoMVC is a great illustration of how far things have come.
Save the element template as a string and set innerhtml of a div as that?
> compromises today that don’t make you re-invent the wheel
Yeah but there's also no need to include jQuery and bog down your site with piles of code you won't ever call just because you don't know how to use the native api like a normal person. React/Angular/whatever are just the latest fad of that mindset, big team corporate ease of use aside.
So yes, this pattern is helpful for solving that sort of thing when it occurs (and if the use case is even substantial enough to warrant it) and Lit looks like it would fit that role reasonably well, but basing the entire site on this principle as a full on framework seems a bit ludicrous.
What html actually lacks is the option to include external html part files, but there are lots of ways to do that serverside that don't involve the stupid idea of putting html into strings in js files for literally everything.
While I would rather nail my bollocks to the ceiling than build a vanilla application (in any stack), there’s no denying the benefit revisiting the basics.
Would you need a “framework” when an app gets beyond TODO? I think you would need to start refactoring your code to be more framwork-like. But this is something we don’t do, and I would say would even be considered “anti-pattern”.
HTML and CSS are actually quite nice to work with, given modern browser developer tools. Much simpler to work with when they are literal files.
It wouldn’t surprise me if people continue to compile other languages to JavaScript or WASM though. It seems reasonable a Java developer might like to work in Java or a Ruby developer in Ruby instead of writing JavaScript. But I don’t understand how people feel confident writing web applications if they don’t take the time to understand CSS, HTML, or the browser APIs.
I'd love to not be able to use them and to create complex UIs in pure JavaScript but it always ends up being painful where you spend more time optimising the rendering than doing any work.
In simple apps I will write UI in a functional matter in pure JavaScript, regardless of the performance implications. But bigger DOM means worse performance with this method.
When will we get to the point where we can tell the browser what we want the DOM to look like and then the browser does the diffing like a framework would?
Remember <meta http-equiv="refresh" content="5"> .
It was discouraged because the back button broke. If you're developing a single page react app, I don't think you care about the back button.
You should though. One easy way is to use react-router. e.g. going to /profile renders the Profile component. Then navigating to /dashboard renders the Dashboard component. Pressing the back button will take you to /profile.
Another pet peeve of mine is people using internal react state when they should just use path or query params to make it transparent and easily sharable.
Your users likely do, so you should too.
There's sort of a "Maslow's Hierarchy of User Needs" that exists in software though. So long as the user can do something, and their immediate needs are met, performance concerns are just a small annoyance. And generally they will continue to ask for more features rather than performance improvements as long as the app remains usable.
Not sure where you think mutation comes into play here, that's an orthogonal concern—you can have an API that mutates some internal representation of a VDOM, and it's still faster than manipulating the DOM directly.
It makes sense to be able to describe what you want to achieve and to let the browser determine how to get there in the most efficient way.
If the browser could do this it would make a tonne of JS code so much simpler. There's a lot that goes into making sure that there's no unnecessary DOM updates because it's just slow.
I don't write assembly and move things between registers by hand, I write a function and the compiler decides the most efficient way of doing it. UI should be the same way, I say what I want to happen and the browser decides how to get there.
This is also something that can be automated by a framework. Check out https://svelte.dev/blog/virtual-dom-is-pure-overhead
Whether that's Svelte without a VDOM or React with a VDOM. The entire point of these frameworks is that you can write complex UI in a declarative way. They both exist because writing it declaratively in pure JS leads to performance issues. But there's nothing stopping the browser implementing something that does this optimisation for you.
If you want to write declarative UI in pure JS then you need the browser to do these DOM optimisations for you, and diffing the changes is the way to do that.
The main bottleneck here are the synchronous localStorage calls happening in the render path, they could be moved to a separate timer.
I still suspect this might be faster than React anyway. Would be interesting to try.
Read my comment again.
It's normal to get much worse performance than React if you layout thrash and it's very easy to layout thrash without batched updates. There's overhead in the vdom but getting all the updates batched tends to be a performance win in any decent sized app. This was an active area of library exploration/development in the 2008-2012 timeframe but the only framework actively promoting it was Sencha IIRC.
- the UI isn’t a source of truth, it’s a computed interface to it
- changes/interactions in the UI should update the source of truth, not other parts of the UI
- the source of truth is fully responsible for managing and notifying dependencies of relevant changes
Or much shorter: state and presentation are separate concerns. Once you have that, you can focus on the actual problems you’re trying to solve rather than the ones created by crossing underlying technology boundaries.
Maybe not “should”, but it’s an incredibly helpful mental model, and I can think of very few cases it can’t model correctly. It’s so helpful a model that it’s gained traction in Rust, Swift, Kotlin, Dart, Go. It’s the ~only model in Clojure and and literally the foundation of Elm.
None of these cases, AFAIK, apply the model literally when they interface with inherently imperative APIs. They provide APIs expressing the model, and manage the imperative behavior on your behalf. This is ultimately how all functions in meaningful programming work. At the end of the day, allocating memory or displaying output is a side effect.
This is also how you can have custom renderers like those used in ink, three-solid, even React Native. The code is modeled as a declarative function of state, implemented as a set of imperative behaviors corresponding to state and dependency changes.
I’ve worked on contentEditable solutions in the past, probably more than most people who didn’t ultimately produce a library from the work (I went mad, literally angry at the complexity of making it a good UX, and gave up). I hope I never have that task again, but if I do… you can bet your ass I’d use a function of state model. It’s the only way I could reason about the problem without going mad.
I'm glad we have frameworks.
Before even considering something like this I’d want to see a style guide and clear definition of where code should live. Frameworks like React do that well. I can expect a random React dev to mostly do similar things.
This has not been my experience. Even experienced software devs will differ stylistically, but intermediate devs often come up with very different ideas about how things ought to work. I suspect this is due to wide variance in awareness of different libraries/platform features/stylistic patterns/etc, a consequence of being in a relatively unregulated industry.
I have worked for companies using React since 2014 and no 2 projects have had the same layout. My current and previous employers have had the closest codebases, but only in terms of directory structure, and even now the current one is changing to become quite different (in a way I think is good, but only time will tell).
It's older though (seems to have been first written 6 years ago) and has significantly more code.
The entire TODO list is rendered anytime a single item is changed/removed/added. The biggest thing frameworks give us is fast, differential DOM updates.
Once browsers add differential update APIs, then we can kiss React and all the other players goodbye :-)
Demo: https://todo-react-redux-noscript.herokuapp.com/
Repo: https://github.com/wishy-gift/todo-react-redux-noscript/
Talk (updated framework): https://m.youtube.com/watch?v=3yY-Z-X3xE4
Helpers to do your own stuff: https://www.npmjs.com/package/@wishy-gift/noscript
Had no idea who was behind it, but I love that they're still contributing back like this.
0: https://developer.mozilla.org/en-US/docs/Web/API/Trusted_Typ...
1: https://github.com/1Marc/todomvc-vanillajs-2022/blob/1c31309...
2: https://developer.mozilla.org/en-US/docs/Web/API/TrustedHTML...
React and other declarative approaches are inherently different. In React I hardly think of when my component renders. In Backbone days, I remember having to debug why some part of code is not running when I'm expecting it to run. React does this really well.
It can get confusing to track down unexpected renders when you think the result of the algorithm should be different, but that’s not really an issue with react so much a the nature of managing complex state, memoization algorithms which potentially use different diffing strategies, and logic which might be mutating state in ways you don’t quite expect, and so on.
People criticize these front end libraries but I’m still impressed by how well state management has been integrated into such extensible and scalable view layers.
I think it hides the complexity by pretending that's not a problem
While events aren’t explicitly mentioned, MDN offers an insightful read:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memo...
Alternately, one can use event delegation [0]. As does React under the hood [1].
0 - https://javascript.info/event-delegation
1 - https://reactjs.org/blog/2020/08/10/react-v17-rc.html#change...
Also the browser doesn't make a distinction to the type of event (such as `click` ), and say "Oh well you can't click on an element not in the DOM, I think I can clean this up"
So no it will not clean it up and it will leak memory, see for yourself
> App.$.filters.querySelectorAll('a').forEach(el => el.classList.remove('selected'));