| ▲ | mike_hearn 8 hours ago |
| So JSX is pure Javascript and not, say, a dialect of XML embedded in JS? Because it sure looks like the former even though it compiles to the latter. React isn't Javascript. It's a franken-language that looks superficially like a mix of JavaScript and XML whilst following the rules of neither. That's why there is such a thing as a React compiler - a good sign that you're not writing JS, which doesn't have compilers. The other hint should be all the new rules you have to follow. React is full of magic syntax that looks like functions, but e.g. you can't call them inside an if statement, or you have to redundantly declare the 'dependencies' (variables you read) and so on. The semantics of React code are very different to imperative straight line code. |
|
| ▲ | jbreckmckye 8 hours ago | parent | next [-] |
| > So JSX is pure Javascript and not, say, a dialect of XML embedded in JS? It would be best to think of it as syntax sugar for create Element() function calls. You enter JSX with angle tags and insert expressions in braces > React is full of magic syntax that looks like functions, but e.g. you can't call them inside an if statement, or you have to redundantly declare the 'dependencies' (variables you read) and so on That's not magic syntax. That's just functions that must be processed in regular order between render ticks. It's not a difficult exercise to write a "plain JS" function that works that way. If you've worked much with closures you can visualise how that would play out. |
| |
| ▲ | conartist6 5 hours ago | parent | next [-] | | Hooks are magic syntax without any doubt. All magic syntax is made up of non-magic parts, that's kinda the point. The way you know it's magic is it shatters the principle of referential identity, which tells you that a variable is itself. It pretends you can use a simpler mental model but you really cannot and must not. | | |
| ▲ | snemvalts an hour ago | parent | next [-] | | You can write const [a, b] = useState('x') in vanilla js and typescript. Hence it is not magic syntax. | |
| ▲ | jbreckmckye 4 hours ago | parent | prev | next [-] | | > The way you know it's magic is it shatters the principle of referential identity, which tells you that a variable is itself When you do a useValue() it is clear you are grasping at something with a larger lifespan than your function. Conceptually it is not much different than int counter() {
static int x = 1;
return x++;
}
Which predates C89, if age is an argument | |
| ▲ | imtringued 4 hours ago | parent | prev [-] | | Hooks aren't magic syntax. The problem with hooks has nothing to do with syntax. The problem is that the React crowd has decided to overload the meaning of a term that has had a reasonably solid interpretation (at least in comparison to the React crowd). "React Functional Components" have nothing to do with conventional functional programming. They inherently (intentionally?) violate the spirit of functional programming through hidden global variables, while pretending that it is still functional, when in reality they should be doing the opposite. They should be upfront about the hack that hooks are. They are not functional, they are merely functions. In all other respects they operate as if the function was a method inside a class and that all hook calls are with respect to an invisible "this" keyword that contains the component's context. Since hooks are not named (which would expose their inherently pseudo-OOP nature), they associate their state through a hidden incrementing counter. It's like you're sweeping all the OOP parts under the rug to pretend to be functional so you can be a cool functional hippie too. | | |
| ▲ | StopDisinfo910 9 minutes ago | parent | next [-] | | > They are not functional, they are merely functions. Functional literally means dealing with functions composition. Free of side effect is not a property of functional programming. Ocaml is functional and has side effects. | |
| ▲ | recursive 13 minutes ago | parent | prev | next [-] | | What makes it even worse is that in order to match the hidden state with the output of a render function, it has to be "reconciled" which uses usually-right heuristics to match the tree structure of the function output to the tree structure in the fiber cache. | |
| ▲ | svieira 3 hours ago | parent | prev | next [-] | | Aren't hooks just composable effects implemented in userland? In fact, Sebastian actually asked the ECMAScript committee for effects a la OCaml 5.0 effects (https://ocaml.org/manual/5.0/effects.html) and React only built their own when the committee said "not right now", if I remember correctly. The thing is ... you can model effects with the Free monad (or with Haskell's Backpack as was on here just the other day - https://news.ycombinator.com/item?id=45221112), so they are definitely "functional", for most variations on the definition of "functional" that I know. | |
| ▲ | mike_hearn 4 hours ago | parent | prev | next [-] | | Yes, that's exactly it. React is presented as functional but it's still just stateful components, except instead of OOP syntax and features making that clear, it's hidden away so that it looks functional without actually being so. This happens because GUIs are inherently imperative constructs. | |
| ▲ | TomaszZielinski 3 hours ago | parent | prev [-] | | Yeah, well put tech wise (the ad personam part puts me off a bit, though). Personally I like hooks quite a lot, but e.g. I feel I have to check once a month or two if a memoized component (that’s „functional” in name) re-renders if its props stay the same and the only change is the state.. |
|
| |
| ▲ | burnerzzzzz 6 hours ago | parent | prev [-] | | > It would be best to think of it as syntax sugar for create Element() function calls Thats what makes it a new language. C is just sugar on top of assembly. Its so strange that jsx needs a buildstep, but misses ton of obvious ergonomics that one could have added. Why className
instead of class? With a buildstep, it would surely be possible to determine if class was a keyword or not based on context | | |
| ▲ | jbreckmckye 6 hours ago | parent | next [-] | | > Thats what makes it a new language. C is just sugar on top of assembly. I think that's a bad example. C isn't a sugar for assembly: For example what assembly code does a function prototype desugar into? Sugars have 1:1 mappings with host code Maybe you're just being rhetorical about the spectrum of macros, sugars, and languages, though. (In my opinion, a better target for that criticism, in JS land, is the Jest test framework, because of all the reordering magic it does that break fundamental ES semantics) > Why className instead of class? This hasn't been a constraint since... I want to say React 18, six or seven years ago? I might be misremembering the history but I think that was only a problem in the Early Days when there was paranoia about whether JSX needed to be conservative with reserved keywords | |
| ▲ | rafaelmn 5 hours ago | parent | prev [-] | | Syntax sugar is language syntax that improves a common pattern from the language (making it sweater). jsx, async/await - things that just abstract common patterns. |
|
|
|
| ▲ | tayiorrobinson 8 hours ago | parent | prev | next [-] |
| > That's why there is such a thing as a React compiler - a good sign that you're not writing JS, which doesn't have compilers. You say that like it's a bad thing - but it didn't stop Babel or TypeScript from being popular, both of which need a compiler. And being honest, I don't like extra tools in my chain, which is probably why I don't use React proper, but that proves you don't need anything React specific for anything other than optimisation The only syntax you really want for React is JSX. Which is just because writing React.createElement("div" ...) every time is unergomomic. JSX isn't specific to React. It could easily be a language feature, in fact it is an OOTB language feature of TypeScript. > React is full of magic syntax that looks like functions, but e.g. you can't call them inside an if statement They look like function calls, because they are. They're not "magic syntax", and in fact, those rules are explicitly because theres no way around that without implementing special syntax |
|
| ▲ | threatofrain 3 hours ago | parent | prev | next [-] |
| Everything has compilers now and we definitely want to go that direction. The no build people aren’t close to building any popular consensus, like not close at all. Even plain JS is compile heavy because browsers are just compile targets. |
| |
| ▲ | recursive 11 minutes ago | parent [-] | | > Even plain JS is compile heavy because browsers are just compile targets. No. Plain JS requires no compilation. |
|
|
| ▲ | TomaszZielinski 3 hours ago | parent | prev | next [-] |
| I can’t recall a single time where I would want to put JSX in an „if” statement.. In fact I can’t recall a single time where I would want to use JSX in a different context than the return value of a render phase. So from my personal experience the things you mentioned are non-issues in practice. Do you have a different experience? |
| |
|
| ▲ | bastawhiz 5 hours ago | parent | prev | next [-] |
| JSX isn't and hasn't even been necessary to use React. The first version of my company's site didn't have a build step and called createElement manually. And in the decade I've been writing for React, I've never used the React compiler. But saying that it's proof that it's not JavaScript it's like saying that V8 is proof that JavaScript is too complicated because otherwise it would be fast enough not to need a JIT. And all those rules? You don't have to follow them either. Use class components. They're still there, and they work fine. |
| |
| ▲ | michaelcampbell an hour ago | parent [-] | | If you also have experience using JSX in a React app, I'd love to hear any opinions/experiences you have with doing the JSX style vs createElement() style coding. I understand how they map to each other but I've only done JSX. That said, I'm old so calling functions all over the place is in my wheelhouse, and I'd love to hear from folks who have done both. |
|
|
| ▲ | gloosx 7 hours ago | parent | prev | next [-] |
| JSX is just a syntax extension to JS, and it's not even required to create a React app. React "compiler" is in fact a transpiler, which is a very common thing in JS. >React is full of magic syntax that looks like functions Full of magic syntax meaning 5 straightforward hooks? Surely they are not true free-form JavaScript, but at least the syntax itself is not turned into a DSL |
| |
| ▲ | patates 6 hours ago | parent | next [-] | | Nitpick: React compiler is not a transpiler. JSX needs to be transpiled, and that's usually done by TS compiler. React compiler is another optional thing on top that's relatively very recent. https://react.dev/learn/react-compiler/introduction#what-doe... | | |
| ▲ | recursive 8 minutes ago | parent [-] | | All compilers translate one language to another language. Historically compilers targeted lower-abstraction languages than the source language. "Transpiler" is a compiler whose input and output abstraction levels are similar. The React cinematic universe has a habit of repurposing existing terminology, but they're both transpilers, to the extent that "transpiler" is even a word. |
| |
| ▲ | sensanaty 7 hours ago | parent | prev [-] | | > 5 straightforward hooks `useEffect` is straightforward? Cloudflare recently (like, literally 4 days ago)[1] had a pretty big outage because of the improper use of `useEffect` (surprise, surprise, it was the dependency array), a hook so infamous if you search "When should I use `useEffect`" you'll get approximately 9 trillion hits, with nearly all of them telling you something different, including Dan Abramov himself having to chip in with multiple blog posts telling people to NOT use it because of how much of a dumpster fire of a API it is. [1] https://blog.cloudflare.com/deep-dive-into-cloudflares-sept-... | | |
| ▲ | gloosx 7 hours ago | parent | next [-] | | Well, that is really embarrassing for Cloudflare... A recursion in a side-effect via dependencies is a rookie mistake, it's hard to imagine it could slip into production with a proper due process. Maybe they should stop vibe-coding and deploying things to production without any tests or review? | | |
| ▲ | sensanaty 7 hours ago | parent | next [-] | | If after nearly a decade swarms of people are still making the exact same mistakes with how they use a specific method exposed by the library, then the problem isn't with the hundreds/thousands of people making the mistake, the design of the method is broken. This type of issue simply does not exist in Vue or Svelte even if people abuse watchers (which I've anecdotally noticed tends to happen from React devs writing Vue code). Also I just want to point out again that Dan Abramov had to write an insanely long guide to using useEffect [1]. This piece is around 10k words explaining in-depth how useEffect works. That is insane for one of the fundamental, core methods exposed by a library. [1] https://overreacted.io/a-complete-guide-to-useeffect/ | | |
| ▲ | 26 minutes ago | parent | next [-] | | [deleted] | |
| ▲ | gloosx 3 hours ago | parent | prev | next [-] | | You know for thousands of years people are still stepping on rake, the spikey part. And they get hit in their foreheads. The rake is lever by design, but I wouldn't say the problem is the rake. | | |
| ▲ | recursive 7 minutes ago | parent [-] | | I've spent more hours using rakes than `useEffect()`, but I've only had the problem with one of them. |
| |
| ▲ | 6 hours ago | parent | prev [-] | | [deleted] |
| |
| ▲ | WickyNilliams 6 hours ago | parent | prev | next [-] | | Disagree about it being a rookie mistake. In the simple case, yes. But consider data used by an effect could travel all the way from root to the max depth of your tree with any component along the way modifying it, potentially introducing unstable references. Maybe it worked when you tested. But later someone introduced a new component anywhere between data source and effect which modified the data before passing it on. That component may have used useMemo. So it looks ok, but it over fires. You become reliant on all your ancestors doing the right thing, in every situation, forevermore. One mistake and unstable references cascade everywhere. The surface for introducing errors is huge, esp in a large, complex codebase. And we have no way to guarantee a stable reference. | | |
| ▲ | gloosx 6 hours ago | parent [-] | | >But consider data modified This is why we never modify data but create new data. Data must be immutable. Strictly typed. Always in the form it is expected to be. Otherwise - crash immediatelly. >But later someone introduced This is why we write integration tests. Introducing anything without tests is only guesswork. | | |
| ▲ | WickyNilliams 6 hours ago | parent [-] | | Sorry I should have been more precise. I don't mean mutation, but taking the data and producing a new (potentially unstable) reference to pass on. Mutating data in react results in under not over firing. It is practically impossible to have full coverage of all code paths in integration tests, since there is a combinatorial explosion of paths. In a case where you have 3 components each with 3 paths you have 27 unique paths. And no app is that simple in practice. It gets out of hand quickly. |
|
| |
| ▲ | TomaszZielinski 3 hours ago | parent | prev | next [-] | | As a rookie with gray hair I completely agree :) | |
| ▲ | 5 hours ago | parent | prev [-] | | [deleted] |
| |
| ▲ | patates 6 hours ago | parent | prev [-] | | Javascript has warts, React has warts, Svelte has warts, Python has warts... It's easy to shoot yourself in the foot in any tech - it's leaky abstractions all the way down after all. useEffect usage needs to die, yes. I don't think it's a case against React, given its age. Otherwise, using React is straightforward. I started coding in it without reading any docs. As someone who used Dojo, prototype, ext.js, jQuery (+UI), Backbone.js, knockout (still has a special place), Mithril, the classic angular, vue (2), svelte, Marko and even Solid (I'm not totally sold on signals), React is the most straightforward by a mile. Is it the most performant? Hell no. Is it the one with the least gotchas/warts? Nope. Concise? A giant no. Batteries included? It depends on what you're looking for... But I can just be productive with it, and it makes sense. | | |
| ▲ | thedelanyo 6 hours ago | parent [-] | | A child who hasn't tasted other mom's food always say, my mom is the best cook in the world. You saying you can be productive in react is just ironic. I just read it as, I can be employable using React. | | |
| ▲ | patates 6 hours ago | parent [-] | | My brain does this sometimes, sorry :) I meant to say, "I can just be productive immediately in React". Not going to edit though. edit: also about the moms cooking analogy... With many of those libs/frameworks, I have much more experience with than react. | | |
|
|
|
|
|
| ▲ | unconed an hour ago | parent | prev | next [-] |
| >The semantics of React code are very different to imperative straight line code. Yes and all you have to do is learn why those semantics exist in order to do react well. Unfortunately too many programmers still think they can just mimic other code to figure it out. |
|
| ▲ | lerp-io 7 hours ago | parent | prev [-] |
| um....react is literally js and its not a language, you can write react with or without jsx which is just syntax sugar to make it look more like html. |
| |
| ▲ | burnerzzzzz 6 hours ago | parent [-] | | “syntax sugar” means its a new language. It has a new syntax. | | |
| ▲ | rkomorn 6 hours ago | parent | next [-] | | This is the first time I've seen someone argue that adding syntactic sugar means creating a new language. | | |
| ▲ | bryanrasmussen 5 hours ago | parent [-] | | it really depends on how much syntactic sugar you add. You could go back 13 years, show somebody some JSX and ask them what language they think it is and nobody would be well that's obviously JavaScript with a bit of sugar on top. | | |
| ▲ | rkomorn 5 hours ago | parent [-] | | Sure, if I'd been replying to a comment that had anything resembling nuance, that would be applicable. It did not. |
|
| |
| ▲ | theshrike79 5 hours ago | parent | prev [-] | | So Python with type definitions (syntax sugar) is a new language? |
|
|