Readit News logoReadit News
have_faith · 3 years ago
> Vue uses a templating language closer to default HTML than to JSX, which makes it much easier to write conditionals and loops in template files, without having to reach for workarounds like map and ternaries

I like react/jsx precisely because I can use language constructs like filter, map, reduce, etc, instead of a custom implementation of basic things like if statements and loops. I find this much more ergonomic and didn’t realise some people see this as a “workaround”.

Worth also pointing out that when you write these templates, as strings or template literals, they might resemble HTML in appearance but really have no relation to actual HTML except what they output after processing. All of the added directives also have no equivalence in HTML. You’re just writing JS indirectly.

snorremd · 3 years ago
This. Most of the value-proposition of JSX is that it is just JavaScript and as such you just write code logic like you would normally do. Need to filter some items? You can do that with the Array.prototype.filter method you already know. Do you need to return a list of components based on some list of object values? Just use Array.prototype.map.

I never really understood those that see this as a weakness and would rather learn a more limited set of template string functions that work kind of like, but not entirely like, the native JavaScript collection functions.

Yes, using a ternary operator in JSX to conditionally render components/values looks a bit ugly, but nothing is stopping you from making a wrapper component like:

<If cond={...}><div>Conditional content</div></If>.

Also with JSX/TSX scopes behave exactly like they do in regular JavaScript, because it is regular JavaScript. Templating languages often invent their own form of scoping mechanism.

jcparkyn · 3 years ago
> nothing is stopping you from making a wrapper component like...

I'd suggest avoiding that, since the inner JX expression will be evaluated even if cond is false. In the best case this just means some unnecessary allocations, but in other cases it can cause unexpected errors (e.g. you check obj != null then try to use it inside the if).

nonethewiser · 3 years ago
> Yes, using a ternary operator in JSX to conditionally render components/values looks a bit ugly, but nothing is stopping you from making a wrapper component like:

Couldn't you put that in a function that returns the correct JSX element or am I misunderstanding the problem? Something like:

  renderThing(number) {
    if(number > 0) return <div>...</div>
    return <div>...</div>
  }


  const Page = () => {
    return <div>{renderThing(someNumber)}</div>
  }

Simple ternaries are fine IMO but thats what I do when the logic gets complicated. I never used a nested ternary in that situation, for example.

marksomnian · 3 years ago
Plus, the power of being able to treat JSX as any other JS object means that you can use standard JS constructs like loops - slightly contrived example:

  const items = [];
  let runningTotal = 0;
  for (const item of someArray) {
    runningTotal += item;
    items.push(<li>Item {item}; running total {runningTotal}</li>);
  }
  return (<ul>{items}</ul>);
The closest example I can find in Vue would require a computed property to implement something like this.

dglass · 3 years ago
Disagree. I would argue your example is hard to read compared to the equivalent in Vue, and it mixes business logic (computing the running total) with the rendering logic.

  <script setup>
    const items = [1,2,3,4,5,6]
    let runningTotal = 0

    const getRunningTotal = (item) => {
      runningTotal += item
      return runningTotal
    }
  </script>

  <template>
    <ul>
      <li v-for="item in items">
        Item {{item}}; running total {{ getRunningTotal(item) }}
      </li>
    </ul>
  </template>
No need for a computed property. Plus, getRunningTotal can be unit tested, or extracted to another file for reusability.

k4rli · 2 years ago
I don't think this is a good way to build JSX from lists. Better to keep components smaller. Also this way will show React linting rules, like the "key" requirement.

  return (
    <ul>
      {someArray.map((item, idx) => (
         <li key={item.id}>Item {item}; running total {idx + 1}</li>
      )}
    </ul>
  );

mmcnl · 3 years ago
It's technically possible, but it looks horrible and should be avoided because of lack of readability. Keep the templates plain and simple, and store your business logic elsewhere.
WuxiFingerHold · 3 years ago
I liked JSX a lot when I was using React. However, writing business or view logic in templates is a maintainability nightmare. With JSX it's very tempting to do this and I did this often, but it's still a mistake and I regretted it every time I visited my spaghetti JSX months later.

When it comes to comparing React with Vue or Svelte, the templating is not the critical factor.

tshaddox · 3 years ago
The JSX bits in a React codebase aren't templates, at least in the traditional sense where a template is a static file that looks like some desired runtime output and contains some "slots" which are analyzed at build time (or program start time) and then filled in with dynamic values at runtime. JSX kinda looks like that, but there is actually no "templatey" stuff happening at build time, i.e. React does absolutely no analysis whatsoever of your JSX and has no idea what it contains until each new time a component renders at runtime.
mmcnl · 3 years ago
I totally agree. Templating is not the critical factor indeed. The templates shouldn't contain business logic so they should be simple by default. If not then you're following an anti-pattern.
the_gipsy · 3 years ago
I get using plain JS, but JS's lack of expression-statements (see rust for contrast) just makes most of it EXTREMELY awkward.

Ternaries, booleans that cast to JSX, switch statements wrapped in IIFs...

bafe · 3 years ago
Once you try any languages where (almost) anything is an expression, it is hard to accept statement-oriented languages
hajile · 3 years ago
The crazy part is that there's not a really good reason why we couldn't make if..else function as either a statement or expression depending on the context. I think there's a proposal to do that.
mmcnl · 3 years ago
This discussion never ends. It's so subjective and totally not important at all. Templates shouldn't contain complex logic anyway, only formatting logic with some for loops. You can learn any syntax in 30 minutes if needed. The battle isn't fought on the hills of templating logic. It's sad because there are many interesting differences other than templating logic between frameworks, but they are less superficial so they get little attention.
tiku · 3 years ago
But you want to avoid using to much code in HTML, because this isn't "page.php?page_id=welcome" anymore..
babyshake · 3 years ago
Especially with copilot, which is clearly well trained on React and JS, I find I often just need to write the first few characters of an array method or other common method and it will generate 10 or so LOC that are at least 90% of what I want.
stevage · 2 years ago
In practice with Vue you tend to write that stuff in JavaScript (eg in a computed property) and keep the HTML as simple as possible.

I've done a lot of Vue and your bit of React and overall I prefer the Vue way here.

yid · 3 years ago
You know you can use JSX with Vue right?

https://vuejs.org/guide/extras/render-function.html

remram · 3 years ago
GP was reacting to this statement from the article:

> Vue uses a templating language closer to default HTML than to JSX, which makes it much easier to write conditionals and loops in template files

no_wizard · 3 years ago
In defense of those directives and template languages, they compile down to efficient operations that every developer can take advantage from. I like that `v-for` is likely more efficient in regards to how it operates than how an average developer might write such a function, especially when dealing with nested data or more complex situations. Other efficiencies can be gained by using a template language as well via the compiler.

Not that you can't with JSX (Solid and Qwik use JSX and have transparent ways of doing optimizations as consumer of those frameworks) but its not currently the default, most (if not all) optimizations must be done "by hand", is a big tradeoff for some places.

MrJohz · 3 years ago
This can be the case, but as I understand it typically isn't so, at least with most big frameworks. For example, I believe Vue templates are typically translated to a hyperscript-like render function that has a similar efficiency to the average React render function. Indeed if anything, I would imagine Vue would be slightly less performant, because the v-for loop is quite abstract and can handle things like looping through objects, so there must be a reasonable amount of machinery to handle all the different loop cases.

The state of the art is less about handling things like loops, and more about reducing the amount of work needed to render static elements. For example, say you have a single component that renders a static table, and in each cell of the table you need to render something dynamic. In the classic vdom system, you'd construct a `table` node, with a `tbody` child, which in turn has `tr` children, which was contain `td` nodes, and then finally in the `td` nodes you render the dynamic content. This works, but most of the content isn't actually changing, only the contents of the `td` nodes. What modern frameworks like Solid and Svelte do is to compile that whole nest of nodes into a single HTML string, and then add instructions that specify where exactly the dynamic content lives. That way, on the initial render, the browser is doing more work natively, and on later updates, only the new content needs to be checked and changed. I know there's a library for React that adds similar capabilities there, albeit with a few more constraints than in other frameworks.

I do know Solid does for-loops differently than in other frameworks, but this is less to do with efficiencies gained by compiling, and more about how to optimally use the signals system that it uses for reactivity. Apart from that, I don't really know of any optimisations that would make something like `v-for` any faster than `.map(...)`.

ThePhysicist · 3 years ago
In general I really like React but after spending years tinkering with JS and seeing my codebases rot away faster than I could keep up due to ecosystem/tooling churn (I started in 2014 when React was ES5 and still using mixins), I started replacing my frontends with regular server-side rendered ones. I enrich these with vanilla JS and some smart things like using async fetch and the history API to seamlessly replace content when clicking links. There are of course solutions like HTMX or Turbolinks that do similar things but it's really easy to make something simple work with just JS.

With some of these tricks the resulting application feels very similar to a real SPA. Of course if you're really building an application in the sense that a lot of the computation and state handling happens in the browser you will still need to use JS, but even then I would just go with vanilla JS in most cases. That said my experience is from building mostly CRUD-like apps alone or in small teams, so I can see the benefit of more complex toolchains in larger organizations.

But yeah, browsers and JS offer so much out of the box, most people don't seem to realize how easy it is to do cool things without relying on frameworks.

verelo · 3 years ago
Ok so this is topical for me right now. I somehow managed to avoid the world of react since it became a thing. All the code i was writing was pre react and we kept the old frameworks, and that’s was all good and well.

Fast forward to today, i took over a project that is full react. What a mental shift. Having said that, sometimes i love it, sometimes i hate it. A friend put it best when he said “i struggle to predict what might be trivial and what will take a full day or two”, and that’s my experience too.

I found myself just the other day wishing i could await the setting of a state variable, it was making saving a file in a complicated form a little difficult. I found a work around but i don’t love it and i know the next time i come back to work on it I’ll be scratching my head at what i was trying to achieve and why i did it this way. Naturally i over commented my rational here.

I do miss writing in basic js and server side code, it’s probably slower over all, but i do miss it for the simple things being predictably simply and the hard things typically being predictably hard.

gabereiser · 3 years ago
You don't need any of it. You can write vanilla JS, using ES6 classes, as web components and be done with the whole front-end framework game. All you need for data-binding is an Observable of some kind that can loop through listeners for events and call their handler. Component classes all have a render function so that React kids feel at home. Those components are registered using CustomElementRegistry.define [1]. Tools like vite help roll up all that code and styles into a minified bundle but doesn't include all the crap that these "modern" frameworks add. Take this from someone who has been writing web sites since 1996. You don't need any of those frameworks unless you're looking to give away control of your product to the roadmap of the framework or need to hire a bunch of people to accomplish something quickly and all they know is React.

[1] https://developer.mozilla.org/en-US/docs/Web/API/CustomEleme...

pcthrowaway · 3 years ago
Not sure if this is what you settled on, but I'd just initialize the state variable as null and then put it into the dependencies of a useEffect that fires when the variable is set
no_wizard · 3 years ago
I realize this is unsolicited advice, however this sounds like you're hitting the "DOM has an imperative API but React is declarative" barrier, because React (until `use` ships at least) has no way to just await reactive values, you can:

if sufficiently complex, you may want to look into `useSyncExternalStore`[0] which can be used to store and update state (IE maintaining UI reactivity) in a microcosm.

Otherwise, I'd recommend framing it as a series of dispatch-able steps, which maps well to `useReducer`[1] possibly in combination with `useEffect`

[0]: https://react.dev/reference/react/useSyncExternalStore

[1]: https://react.dev/reference/react/useReducer

bluefirebrand · 3 years ago
> I found myself just the other day wishing i could await the setting of a state variable, it was making saving a file in a complicated form a little difficult.

It used to be that React.setState would accept a callback function to fire after the state was set.

The newer setter function returned by useState doesn't have that anymore I'm pretty sure. Tbh I've never tried though.

test098 · 3 years ago
if you need to await a setState call, you're prob structuring your logic in a less-than-efficient way. in whatever handler is calling setState, you should compute the next state in the handler, setState(nextState), then use that nextState for whatever comes next.
nymanjon · 2 years ago
Yeah, for my personal apps I just write offline-first apps. I need to make it so I can build apps as efficient as I can as I don't have a lot of free time. So, I wrote a little library under 1kB that just finds where I left off and re-centers/focuses there. It makes for dead simple applications.[^1]

I also created an HTMX-like library that is focused on forms so it stays to the HTML speck pretty closely. I need to make a couple of corrections to it. But it is amazing how far it can get you and much smaller footprint than HTMX. Granted, it can only do a fraction of what HTMX can do.[^2]

For anything stateful I just use web components.

[^1]: https://github.com/jon49/mpa-enhancer

[^2]: https://github.com/jon49/htmf

bravura · 3 years ago
Can you talk more about more of the tricks you use, with server side rendering and light JS?

What about things like real-time (pushed preferably) updates based upon db changes, or another API finally sending streaming results, etc

the_gastropod · 3 years ago
Tools like HTMx [1] and Turbo [2] have pretty elegant and simple solutions to deal with Websockets.

[1] https://htmx.org/extensions/web-sockets/

[2] https://turbo.hotwired.dev/handbook/streams

0xblinq · 2 years ago
Polling is fine for 99% use cases. Even Amazon does this.
d0100 · 3 years ago
This sentiment makes sense up to the point where you are being glared at by a sweaty PM that can't understand why your foo widget can't be moved to the other side while blinking and ajaxing because HTMX doesn't work like that
kerkeslager · 3 years ago
Uh... what? You can totally do that easily. Not that you should, but this isn't harder to do in HTMX.
0xblinq · 2 years ago
I’m using this approach for a side project and it works great. Just traditional express, tagged template literals (with some xss escaping helpers) and stimulus + turbo. Using vite for bundling and reloading on changes.
unsupp0rted · 2 years ago
I used to do this too. Express + PUG templating. Maybe a little <script> injected VUE on the front end for some light client side stuff.
jmondi · 3 years ago
What language and/or framework doesnt have this problem?

- Ruby - if your Ruby/Rails app falls behind, you will be paying back debt to get it up to date

- PHP - if your Laravel/CI/Cake/Slim/Symphony App falls behind, you will be paying back debt to get it up to date

- Go - if your Go app falls behind, you will be paying back dept to get it up to date

- Python - if your Django app falls behind, you will be paying back debt to get it up to date

- Elixir - if your Phoenix app falls behind, you will be paying back debt to get it up to date

kerkeslager · 3 years ago
Having spend over a decade in Python backend/JS frontend ecosystems at this point, I can confidently say from my experience that Django backends are much easier to update than React frontends. If you import every bleeding-edge nonsense through pip that you can, there can still be problems, but Python has a better culture around this, so it's usually easy to steer teams away from doing this. In JS, importing every bleeding-edge nonsense through npm that you can is the only culture I've found, and this problem is pervasive enough that even guarding your direct dependencies doesn't isolate you from it, since your dependencies are likely to introduce bad dependencies of their own.
tl · 3 years ago
All 5 of those age better than React. Also, you are conflating languages and platforms.

Counterexamples / Retorts:

- https://catonmat.net/5-best-programming-languages

- https://stevelosh.com/blog/2018/08/a-road-to-common-lisp/

Choose ecosystems free of hamster wheels, friend.

the_gastropod · 3 years ago
Of course any system will require maintenance. The question is more about the significance and frequency of the maintenance required.

You can take a Ruby on Rails app from 2005, and it will mostly look the same as a 2023 Rails app. You'll need to update some gems, use the newer routing DSL, and update the environment configs. But that's pretty much it, after nearly 2 decades.

Contrast that to a React app written 5 years ago, where you'd pretty much need to completely rewrite everything (class components => functional, use hooks instead of callback methods, etc.)

DangitBobby · 3 years ago
I've just updated a codebase from Django 3 to 4, about to do another one. It took very little time, with 0 breaking code changes and a mandatory postgres update to 12+.

Even going from pandas 1->2 and celery major version bump (5, I think) caused 0 problems. Mature codebases like these tend to be careful about backwards compatibility.

Daishiman · 3 years ago
As someone with over a decade of Django experience, _very little_ has changed in Django since it started; you can bring up a very old app to speed in a matter of a couple of days.

I've had to spend a week moving a 3 year-old React app to the latest versions and failed because certain dependencies were just a mess.

2023throwawayy · 3 years ago
I have CakePHP code bases that are over a decade old and still run fine.

Go is backwards compatible.

robertoandred · 3 years ago
No don't you see, it's their preferred language so its maintenance and churn don't count.
icedchai · 3 years ago
I have 10+ year old sites on PHP 5 and Laravel 4.x that the client doesn't want to pay to upgrade.
jchw · 3 years ago
Web Components have got to be the single most overrated web feature I've ever witnessed in the many years I've been messing around with browsers. You know, even WITH React and no Web Components, there was already a pretty reliable way to integrate third party libraries into React without a ton of glue: the DOM. Like for example, if you want to integrate a text editor like Monaco or Quill, basically all you have to do is give it a DOM node and tie together whatever props/events/bindings you want. You don't really need monaco-react, which is not even a large library to begin with.

The main reason why React is still popular is, drum roll please... The programming model. JSX is not an antiquated idea, it is still one of the better ways to integrate the UI part of a JS application into the JS part directly. I greatly prefer JS logic inside of my HTML versus a bespoke template language specifically because it's easy to compose and construct complex logic in.

I've been messing around with Svelte a bit in spare time. I really like Svelte and will probably continue to use it, but the two things I will note is:

- The integration with Web Components is imperfect and doesn't really hit me as something I would seek out.

- The templating logic in the HTML feels decidedly inferior versus just being able to use JS logic and JSX. Try doing a for loop where you count up; the best answer I could find on the internet was to construct an Array using `Array(number)` and enumerate over it...

What I really want is actually more like React's programming model with Svelte's "compiling down to nothing" mantra.

But this Web Components fervor, I know people get very heated about it, but I strongly believe that in 10 years it's going to be one of those grotesquely complex legacy features nobody can get rid of.

FireInsight · 3 years ago
SolidJS sounds exactly like what you want https://www.solidjs.com/
jchw · 3 years ago
That looks great. It doesn't mention compiling down to nothing, but it definitely offers the programming model of React Hooks without needing a virtual DOM, which is already a good innovation, and probably something I'd like more than Svelte.
Izkata · 3 years ago
Once upon a time, I remember one of the plans for React was the ability to compile components into web components. Your code wouldn't have to change at all, but it would mean CSS couldn't leak in/out of the component boundaries like it does now. I think it would've also made it easier to use a React component in other frameworks, since all they'd see is the common web component interface instead of the React interface?
troupo · 3 years ago
> I remember one of the plans for React was the ability to compile components into web components.

This was also the case (-ish) for Vue, Svelte, Solid. Their authors were really bullish on web components in the beginning. Now they are all on the scale from extremely negative towards them to completely indifferent.

gabereiser · 3 years ago
While JSX is very well suited for programmatically defining your UI, it's about all that React is worth these days. You know about string literals right? You don't need JSX and in-fact can get away with:

   render(props) {
      return(
         `<div>
         {props.value}
         </div>`
      );
   }

intrasight · 3 years ago
My perspective is that JSX is all that React has to offer. And lots of developers - myself included - were doing "JSX" a decade before React arrived. Because it, like, super obviously a good idea.
coding123 · 3 years ago
what's going to make sure you didn't type <div></dib>
ufo · 3 years ago
Watch out for html escaping.
text0404 · 2 years ago
you know about injection vulnerabilities, right? if you really want to spaghetti code your app with string representations of html, you can also use `dangerouslySetInnerHTML` in React.
tehbeard · 3 years ago
For your div demo, sure, heck even the "todoapp" might work well enough with it.

But please, build something proper with just that and presumably a .innerHTML = ...

Let us know how it goes :)

draw_down · 3 years ago
Hmmmm. Does that do escaping and such, or are you boned when an angle bracket shows up? Plus if the nodes are already parsed in your code it kinda sucks to stringify them so the browser can re-parse them.

Not to mention holding focus and other element state, would that just get blown away and replaced with a whole new element every time? (Where react does tree reconciliation to avoid unnecessarily blowing away and replacing elements)

Maybe you’re only addressing the point about programming model, but this approach seems like it has some issues.

TehShrike · 3 years ago
The shadow DOM is a great alternative to using iframes to get style isolation from the larger app, but everything else about custom elements/"web components" has better alternatives in user-land.
arve0 · 2 years ago
Each loops over anything with a length property:

    {#each {length: 3} as _, i}
https://stackoverflow.com/questions/58213585/svelte-3-how-to...

jchw · 2 years ago
That's not really a huge improvement over just making a sparse array though, is it? Looks more confusing to me. Could be wrong but I'm pretty sure e.g. Array(1000000000) does not actually allocate much.
jimmont · 2 years ago
captain obvious here, Polymer became LitElement which became the invisible Lit.dev (branding direction on par with twitter becoming x); pretty much state of the art on top of web components; not that anyone noticed, as I said--meetup.com keeps prompting me to take over one of the web component meetups where the (or one of) lead of the project can't seem to muster the effort. a bit frustrating when the lack of awareness is so profound and extensive--as evidenced by many of these comments, over many years. I'm sure many more projects will make the mistake of choosing React and Svelte before the conclusion mentioned here bubbles up.
plopz · 3 years ago
I think JSX was a mistake and just using hyperscript would have been better for the ecosystem. I think frameworks peaked with mithril and have been downhill ever since.
omnimus · 3 years ago
Mithril wasnt back then what is it now.

Deleted Comment

aatd86 · 3 years ago
How does one "react" to changes in a foreign element? Mutation Observers?
horsawlarway · 3 years ago
Those other tools you're using almost always give you a set of callbacks or events they will fire.

Just use the normal event handlers. If you're tied into a store (ex: redux/zustand/recoil/context/etc) just update the store from the non-react library and things will work themselves out just fine.

You can watch the DOM with mutationObservers, but if you own both pieces (react and non-react) why would you bother? They can both coordinate just fine.

MutationObservers really shine when you happen to missing an eventHandler you want in a library, or you're running on someone else's DOM so you don't control both sides (ex: you're an extension content_script).

diordiderot · 3 years ago
> React's programming model with Svelte's "compiling down to nothing" mantra.

Solid JS!

awestroke · 3 years ago
I think the people expressing negativity about hooks are a small minority. Hooks are a massive step up from class component lifetime methods, and the composability of hooks can lead to some very clean and powerful code if you know what you're doing. We're using hooks at work, with rules-of-hooks linting, and I can't remember the last time we had an issue or bug because of hook semantics
nicoburns · 3 years ago
I think they're a bit of a mixed blessing. The way they can decouple business logic from view logic is absolutely fantastic. But having to wrap everything in useCallback and useMemo to avoid re-renders is a bit of a footgun and a step backwards from class components.
ElKrist · 3 years ago
Like others I disagree that you have to wrap _everything_ in useCallback/useMemo.

However saying you only need those for performance reasons is wrong.

There are cases where avoiding re-rendering (thanks to useCallback) is avoiding an infinite loop.

I created a codesandbox[1] to illustrate this. Wrapping the "reset" function in a useCallback solves the infinite loop.

If your initial reaction is: "you should not create logic like this" or "you're adding unnecessary stuff" please note that this is a stripped down version of a real use case, where things make more sense.

The point is that it's hard to come up with a rule as to when to use useCallback. The best I can think about is: "if you don't have direct vision on where your function will be consumed, wrap it in useCallback". For example, when your function is defined and returned in a hook or defined in a parent component and given to children.

The point is that any of those children/consumers could have this function in a useEffect and so list it as a dependency of this useEffect.

[1]: Warning, clicking "Start" creates an infinite loop in your browser. https://codesandbox.io/s/intelligent-rgb-6nfrt3

tobr · 3 years ago
> The way they can decouple business logic from view logic is absolutely fantastic.

It’s a great idea to decouple business logic from view logic, but then hooks are the wrong place to start. Last time I checked, you couldn’t use them at all outside of a React component. That’s just a terrible place to put your business logic if you want it to be isolated from the specifics of your view.

I’ve mostly moved away from React, so maybe this has changed recently, but it seems difficult considering the fundamentals of their design.

jacobedawson · 3 years ago
Best practice in general is not to use either of those hooks unless you notice performance issues, or have a good reason to, React is optimized pretty well and unless there are serious numbers of rerenders happening they aren't noticeable.

Josh Comeau has a nice overview of useMemo and useCallback, one of my favourites: https://www.joshwcomeau.com/react/usememo-and-usecallback/#w...

kfrane · 3 years ago
Hooks are a step in the right direction, I just have a feeling that having to wrap in useCallback and useMemo and having to add dependencies manually can't be the final step of web app development. I look into the author's suggestions for the next generation of hook api in other libraries. However, I still don't want to rely on those libraries in large long living projects.
threatofrain · 3 years ago
The React team is testing out a compiler time approach to useMemo instead.
SkyPuncher · 3 years ago
We wrap very little in those methods and things are just fine.
bcherny · 3 years ago
My understanding is you don’t usually need useMemo and useCallback, unless you’re seeing performance issues and your profiler is pointing at un-memoized code as the culprit.
3cats-in-a-coat · 3 years ago
I sometimes check React discussions and it's full of new made-up terms about managing issues that are uniquely caused by React or some previous iteration of a React technique. What happened with the simplicity of just "generate some boring ass HTML DOM in JSX, and it applies the diff to the actual DOM". That's it. That's the entire value proposition of React and it needs no hooks, handles, states, immutables, events, data trees, properties, arguments, components, nothing else. Oddly that still works just fine, but no one uses React this way anymore.
rewmie · 3 years ago
> I sometimes check React discussions and it's full of new made-up terms about managing issues that are uniquely caused by React or some previous iteration of a React technique.

In other words, you're checking React discussions and finding discussions on how to maintain React code. What were you expecting to find?

> What happened with the simplicity of just "generate some boring ass HTML DOM in JSX, and it applies the diff to the actual DOM".

React happened, which does just that but transparently and effortlessly. In fact, React does it so well that a concern is to prevent it from applying those diffs when being updated when it doesn't need to.

> That's it. That's the entire value proposition of React and it needs no hooks, handles, states, immutables, events, data trees, properties, arguments, components, nothing else.

React does not need those features if you are using React for things other than developing graphical user interfaces, which by their very nature are stateful, emit and react to events, handle properties, etc.

peddap · 3 years ago
Only if you're working on super simple projects. Or don't want reusable code.

How do you share data fetching logic across components

How do you share a common UI functionality like toggling states, starting timers, across components?

People are now more concerned about clearly writing business logic while stiching together React lifecycles methods, instead of the other way.

sfvisser · 3 years ago
React went from class components to function components and from lifetime callbacks to hooks. These concepts are completely orthogonal.

There exist design choices that would end up with a different combo. Class components with hooks or function components using lifetime callbacks.

Yes, hooks — basically sub components with possible effects and yielding values, or DOM output — are a terrific idea and much more functional and principled than explicit lifetime callbacks.

All the dependency arrays and non-conditional checks etc are because of the function components approach and don’t have much to do with hooks.

I feel nearly every discussion on hooks mixes this up and makes the whole conversation just weird and confusing.

troupo · 3 years ago
> All the dependency arrays and non-conditional checks etc are because of the function components approach

And because of React's design choices. Reactivity can be achieved without explicit dependency lists.

mattkenefick · 2 years ago
I think you're underestimating that.
mcv · 3 years ago
I'm not a hardcore React user; I'm currently working with React, but I came here through jQuery, Angular 1, web components, and Vue. I've done two React projects: one really tiny one as an assessment where JSX was an eye-opener; components were classes, and React was simple and fun back then.

Now I'm working on a gigantic React project, and I'm surprised it's still working. It's all based on function components with all the hooks, higher order components, middleware components, and tons of other stuff. It works, and it's clearly maintainable, but it's not pretty. Endless useEffects after each other make it hard to see what's going on. Every change requires changes in half a dozen files at least; DRY is clearly not a concern here.

I'm not a React expert, but I think function components and hooks were a mistake.

One thing that strikes me is that years ago everybody was excited about ES5 finally adding classes, and now everything seems to be moving away from classes.

I think JSX is still a cool idea and an interesting alternative to templating, but I also think that if I were to pick a frontend framework now, I'd go with Svelte.

moomoo11 · 3 years ago
If you have lots of useEffects and the code is confusing, that just means you're not writing your code well. I've architected and shipped multiple react projects that generate min 100M + USD in revenue, so I'd say I'm well versed in production react. It is weird, sure. All web technologies are kind of weird. But it works great for large web applications.

Keep your functions small. Re-use is key - whether its hooks or components. Keep state sane by writing small functions that handle a couple state items internally, or create a parent state using context around a group of components.

React gets a lot of hate, but most of it is unfounded. It is just a tool. I see people write 800+ loc react components and wonder why it is "so confusing". The problem is obvious. The goal of using any technology is to make money, nobody cares (end of the day, just being real lol) about any of these esoteric practices that happen under the hood with effects, etc. Write good code and most problems disappear.

Unless you're working at Meta on react, or you have some burning desire to build tools like this (and honestly only <5% of devs who contribute will contribute something meaningful), there's no reason to pick so many fights with these tools.

Just use it by accepting its features and limitations, and craft your UI project well enough that it is maintainable and keeps printing money. Anything beyond that is a waste of time/effort.

fud101 · 2 years ago
Any good resources to learn more on this (working with production react)?
squidsoup · 3 years ago
Endless useEffects is an indication that useEffect is being used incorrectly. In mostly projects you should only see a few instances of useEffect.

This might be helpful https://react.dev/learn/you-might-not-need-an-effect

com2kid · 3 years ago
If the same problem pops up a lot when using a framework, then at some point the framework is to blame. Yelling at developers "you are doing it wrong!" is meaningless, frameworks should naturally lead people towards the correct behaviors.

React does no such thing.

jzig · 3 years ago
I find Angular much easier to reason about than the current state of React/Next. Which is funny because the biggest criticism of Angular years ago was its learning curve. Yet React seems to have become even more convoluted.
ecshafer · 3 years ago
React and angular both had much bigger learning curves than vue. But between google and Facebook, I don’t think vie stood a chance popularity wise, even though I think it was the better of the frameworks at the time.
jitl · 3 years ago
One reason you don’t want a class for every component is that standard JS minifiers won’t compress method call names, but can compress imported function names. So the cost in the minified bundle between a class component and an equivalent function component is huge, multiplied out by the complexity of the component.

`this.handleClick` vs `c`.

I still use classes for building data structured but don’t think creating classes should be encouraged by a framework.

Brybry · 3 years ago
> So the cost in the minified bundle between a class component and an equivalent function component is huge

Does this actually matter though? It's going to be gzipped anyway right?

Xt-6 · 3 years ago
They can do it, it is just turned off by default and require more advanced configuration.

https://github.com/terser/terser#cli-mangling-property-names...

_fat_santa · 3 years ago
> One thing that strikes me is that years ago everybody was excited about ES5 finally adding classes, and now everything seems to be moving away from classes.

For me the key advantage is much less boilerplate, readability and portability. The problem with `Stateless` components up until the introduction of hooks is that if you wanted state you had to write your component as a class so you ended up with components written in two totally different syntaxes with one being much more heavy on boilerplate.

The last key advantage i see is it brought the "React Components" way of sharing to logic. Previously every piece of logic you shared had to be connected to a react component, so you ended up with many "Providers" that were just a div with logic. Now with Context and Hooks you can easily transport that logic without the use of a Provider (well you still need one with Context but that a slightly different story).

mcv · 3 years ago
Makes sense. I'm not sure I've ever written a stateless component. Almost every non-trivial component is bound to have some sort of state, doesn't it?

Deleted Comment

batmansmk · 3 years ago
The article starts by a quote of Alex Russel, paid by Google to specify Web Components between 2008 and 2021 - a technology in direct competition with React at the time. He is not a technologist to track or quote to get unbiased framework opinions.

I don't agree with most of the argument here, to the point where I think we live in totally foreign echo chambers that rarely exchange ideas. I didn't get any new idea out of this article, it didn't inspire me to do something I already tried 10 times in the past.

The website loads fast, and that's great. 10% of the CSS is unused. and that's a small blog. In the non-themed CSS, it's close to 50% unused. You could consider it a non problem - at scale dead CSS is complicated to manage, at least for me.

afavour · 3 years ago
> paid by Google to specify Web Components between 2008 and 2021 - a technology in direct competition with React at the time

I’m personally of the belief that we should assess arguments, not employer. Someone working on a competitor to React can make very valid arguments against it, they’re often some of the most knowledgeable people about the drawbacks of the framework.

I’m personally not a fan of Alex’s abrasive style but I’ve seen plenty of his critiques of sites written in React-based stacks and they’re usually evidenced with bundle analysis, burn down charts and so on. They’re not unfounded.

(I also disagree that Web Components are a competitor to React. Frameworks like Preact and Svelte are interoperable with Web Components and build on top of the API. React chooses not to but that’s neither here nor there)

flakiness · 2 years ago
> (I also disagree that Web Components are a competitor to React. Frameworks like Preact and Svelte are interoperable with Web Components and build on top of the API. React chooses not to but that’s neither here nor there)

Used to work on Web Components (the browser side.)

Although we didn't take it as a competitor, in hindsight it was - at least in a sense. Both are component-based technologies, and the expressiveness of React and ES6+ made WC less relevant. I think WC is still nice to have, but it is no longer a must-have as it was originally envisioned.

The JS ecosystem has largely solved the problem by themselves without browser vendor's help (besides improvements of JS itself.)

jitl · 3 years ago
Neither Preact or Svelte produce web components by default or use features like Shadow DOM.
hasanhaja · 3 years ago
I don't feel it's fair to brand "web components" as a technology that was in direct competition with React. I think the nuance matters.

They may have been solving similar problems then, and they may be optimized for different things now. But Web components are a web standard, and React is not. Pushing for web standard technologies is inherently unbiased because that's just betting on the platform. This results in pushing for platform improvements (like declarative shadow dom so it plays well with SSR, etc), and then everyone benefits.

IMO it'd only be a bias take if web components were branded as having no issues whatsoever, or that they are the most optimal solution for everything. I think it's okay to say, "web components currently don't solve my problems and that's why I'm looking to use something else like React or Solid". However, I've not seen this sentiment shared when it's the other way around with React. It's always "no one got fired for picking React" instead of actually evaluating what will deliver the most value to your users.

pcthrowaway · 3 years ago
> Pushing for web standard technologies is inherently unbiased because that's just betting on the platform.

There's a ton of politics around web standards, and you can bet if Google manages to push through Web Environment Integrity, I will not consider people suggesting to use it "unbiased because it's a standard"

troupo · 3 years ago
> I don't feel it's fair to brand "web components" as a technology that was in direct competition with React. I think the nuance matters.

Nuance doesn't matter to most proponents of web components. When they were introduced, for the first few years they were explicitly marketed as platform-native solution that makes frameworks obsolete.

Now the rhetoric seems more nuanced, but it's the same. It's only been upgraded to "build with lit".

> IMO it'd only be a bias take if web components were branded as having no issues whatsoever, or that they are the most optimal solution for everything

Mostly they are billed like that. And any voices criticizing them are either ignored or blocked.

dahwolf · 3 years ago
I'd take that point further and state that React is in no competition with anything.

React was invented because Facebook had very interactive/stateful UI as well as large teams of developers working on the same codebase. The then conventional jQuery soup approach didn't cut it.

Should the web platform come up with a standards-based approach to solve the same problem, then this is not "competition", it is a blessing. It's not like React earns Facebook any revenue. Ideally, it wouldn't be needed or exist at all.

batmansmk · 3 years ago
React has more implementation of its components model (preact, react, solidjs, inferno,…) than web components (chrome, ff partially and safari partially), is more used and is more indépendant from the current web monopoly. Anything w3c is now a standard to keep dominance.
Kevin2379 · 3 years ago
Interesting article. I’m going to play devil’s advocate and come at it from a business perspective. There are huge advantages to sticking with an industry standard. It makes it much easier to hire devs. If you’re a dev it makes it much easier to get work. Having a big ecosystem means less building from scratch. There are huge network effects at play. In order to get serious traction in a market with network effects, the alternative doesn’t need to be a bit better, it needs to be 10x better. React displaced jQuery because it was 10x better. None of these alternatives strike me as being 10x better at this point. Sure they’re a bit easier for devs and a bit faster, but I’ve never had a customer complain that the app took 500ms to load instead of 250ms. There’s other things they care about a lot more. At some point another framework is going to displace React, but I think React still has a huge advantage at this point.
stevage · 2 years ago
Yeah, I'm currently working for a project that rewrote their whole platform from Vue to React simply because they couldn't find enough Vue devs.
inv13 · 3 years ago
A well put together article.

I still remember the day when angularjs was a new thing(around 2015 perhaps) and as a newcomer I was sucked into it. Just loved the thing. A year later, there were news about Observable JavaScript objects. So objects could send a notification about themselves having been changed. And when do so, do DOM changes could be done accordingly, without having to implement a render algorithm and having to compare shadow nodes with new render results to see what changed every time any data change occurs. I don't think we are past that with React, and as the author mentioned there should be absolutely no reason for a developer to worry about rendering performance (the amount you have to use react, with for example useMemo, useCallback) and is something to be looked after and questioned.

Another argument of mine[0] would be the definitions that have been introduced by react. Component, state, hooks. It seems like we have forgotten about what they are actually called, and its function is in the context of programming (functions, variables, events, etc.). And so people become solely a React developer and can't really see a way out. (from the article: "And maybe—just maybe— your current satisfaction comes, at least a little bit, from simply not knowing what you’re missing.")

[0] - https://medium.com/@ngergo/describing-how-react-works-in-com...

test098 · 3 years ago
> there should be absolutely no reason for a developer to worry about rendering performance

i have a csv with one million rows. should i load the entire thing into memory and render 1m * column_count dom elements?

> Another argument of mine[0] would be the definitions that have been introduced by react. Component, state, hooks. It seems like we have forgotten about what they are actually called, and its function is in the context of programming (functions, variables, events, etc.).

a Component is a Component because it represents a node in the React tree. not all functions are Components.

state is state because it's more than a variable - updating it triggers re-rendering. a normal JS variable does not come with this reactivity.

hooks are not events. they are wrappers for reusable logic.