top | item 46665252

(no title)

blakewatson | 1 month ago

Related: This is a nice write-up of how to write reactive jQuery. It's presented as an alternative to jQuery spaghetti code, in the context of being in a legacy codebase where you might not have access to newer frameworks.

https://css-tricks.com/reactive-jquery-for-spaghetti-fied-le...

discuss

order

lioeters|1 month ago

This brought me flashbacks of jQuery spaghetti monsters from years ago, some were Backbone related. In retrospect, over-engineered React code can be worse than decently organized jQuery code, but some jQuery mess was worse than any React code. So I guess I'm saying, React did raise the bar and standard of quality - but it can get to be too much, sometimes a judicious use of old familiar tool gets the job done.

epolanski|1 month ago

You reminded me of a time where one of my clients asked me to add a feature on a file uploader written in react/redux. This was early 2021.

I kid you not, there were 30+ redux actions chaining in the most incomprehensible ways, the form literally had a textual input, a button to open the file explorer and a submit button.

It took few weeks one of their Romanian team to build it and apparently that team was reassigned and nobody could touch it without them.

I remember writing pages and pages of notes to understand how this all tied up in those extremely complex chains and claiming progress after few hours when I achieved to simplify the flow by removing a handful of these actions. Hooray.

Then it suddenly dawned on me that...I could just rewrite it from scratch.

Nuked the entirety of that nonsense and replaced it with a single useState in a matter of few hours also implemented the newly requested features.

The client could not believe my progress and the fact I also removed many of their previous issues.

Then I had a second realization: React was useless too and it got dropped for native HTML forms and a handful of JS callbacks.

Sammi|1 month ago

I hear you saying that React raised the floor but also lowered the ceiling.

TuringNYC|1 month ago

>> This brought me flashbacks of jQuery spaghetti monsters from years ago, some were Backbone related.

To be fair, jQuery was a response to the the IE and JS variant mess of the early 2000s. jQuery made development possible without debugging across three browser varients.

root_axis|1 month ago

React made complex interactive UIs a lot easier to manage than jQuery, but that resulted in many developers adding a lot more complexity just because they could.

Klaster_1|1 month ago

I used this approach before and it indeed works better than the 2010-style jQuery mess. A good fit for userscripts too, where the problem you attempt to solve is fairly limited and having dependencies, especially with a build steps, is a pain. Note that you don't need jQuery for this at all, unless you are somehow stuck with ancient browser support as a requirement - querySelector, addEventListener, innerHtml - the basic building blocks of the approach - have been available and stable for a long time.

doix|1 month ago

Unfortunately, nowadays writing userscripts is much harder than it used to be. Most websites are using some sort of reactive FE framework so you need to make extensive use of mutationObservers (or whatever the equivalent is in jQuery I guess).

augusto-moura|1 month ago

In ol'times people used BackboneJS[1] for that purpose. And surprisingly enough, it is still being actively supported[2].

If someone is still using jQuery for legacy reasons, BackboneJS might be a good intermediate step before going for a modern framework. Backbone is pretty light and pretty easy to grasp

[1]: https://backbonejs.org/

[2]: https://github.com/jashkenas/backbone/tags

Izkata|1 month ago

There was a period where BackboneJS models were used as the datastore for React, before Redux took over. I haven't used it like this myself, but could definitely see it as a way to do an incremental rewrite.

mb2100|1 month ago

That's a very nice pattern indeed. If you add signals, the update function even gets called automatically. That's basically what we do in [Reactive Mastro](https://mastrojs.github.io/reactive/) ;-)

1123581321|1 month ago

The last major jquery app I wrote ended up using a similar reactive pattern. I had to shoehorn a custom search engine frontend into a Joomla CMS where I wasn’t allowed to change much. Good times!

kccqzy|1 month ago

But if you do that, you'll also find it easy to write plain JS without any libraries or frameworks. document.querySelectorAll is just slightly more verbose than $(). I have personally done this: for simple web pages, I just eschew all dependencies and write plain JS.

insin|1 month ago

This is still the way - jQuery or not - for UI where you can't/don't want to use a component library. I use the same approach for my browser extensions, both for page scripts and options pages. Writing features so you update state then re-render also means you get things like automatically applying option changes live in page scripts, rather than having to reload the page, for free. Just receive the updated options and re-run everything.

Browser extension options pages are mostly a form mapped to what you have stored in the Storage API, so implementing them by handling the change event on a <form> wrapping all the options (no manual event listener boilerplate) then calling a render() function which applies classes to relevant elements (<body> classes are so good for conditionally showing/hiding things without manually touching the DOM), updates all form fields via named form.elements and re-generates any unique UI elements makes it so un-painful to change things without worrying you're missing a manual DOM update somewhere.

My options pages are Zen Garden-ing 5 different browser-specific UI themes from the same markup to match their host browsers, which is a brittle nightmare to maintain in an app which needs to change over time rather than static demo HTML, but once you've tamed the CSS, the state handling and re-rendering is so painless I'm sticking with it for a while yet, even though it would be long-term easier if I used Preact+htm for no-build option components which know what the active theme is and can generate specific UI for it.

My favourite dirty old-school knowledge is still the named global created for an element with an id, why bother selecting an element when it's right there (once you know you need to avoid global name collisions)?. I use those suckers all the time for quick fun stuff and one-off tool pages.

    <h3 id="communityNoteHeading">
      Readers added context they thought people might want to know
    </h3>
    <div>
      <textarea id="communityNote" placeholder="Note" rows="5" style="width: 400px"></textarea>
    </div>
    <button id="communityNoteCopyButton" type="button">Copy</button>
    <script>
      communityNoteCopyButton.addEventListener('click', () => {
        navigator.clipboard.writeText([
          communityNoteHeading.innerText,
          communityNote.value,
        ].join('\n\n'))
        communityNoteCopyButton.innerText = 'Copied'
        setTimeout(() => communityNoteCopyButton.innerText = 'Copy', 1000)
      })
    </script>

davidzweig|1 month ago

MobX autoruns happily call jQuery functions.