4 ms·
They can't. The ecosystem has too many dependencies that break at this point. Consider that Target.com, Walmart.com, Microsoft Teams, and untold masses of sit
by CharlieDigital 3y ago
They can't.
The ecosystem has too many dependencies that break at this point. Consider that Target.com, Walmart.com, Microsoft Teams, and untold masses of sites are React.
The huge component ecosystem.
Entire companies built around it.
The core concept is broken§, but fixing it means possibly breaking everything else. If you're going to break everything, might as well use something else.
All we can do is truck along at this point; stuck with React because of the mass of the dependencies.
§ React is the only library/framework that is opt-out of re-render while Vue, Solid, Preact, Svelte are all opt-in. This is one of the core reasons it's hard to do right and prone to a specific class of bugs that rarely -- if ever -- show up in other frameworks as you constantly have to be aware of opting out, even in what seems like normal JavaScript.
- lacrimacida 3y agoCould you explain how the opt out/opt in works? Im a bit confused
- CharlieDigital 3y agoTake this example: const { useState } = React; function Person(props) { console.log('Render Person'); return (<span>{ props.identity.firstName } { props.identity.lastName }</span>); } function App (props) { console.log('Render Hello'); const [count, setCount] = useState(0); const einstein = { firstName: "Albert", lastName: "Einstein" }; return ( <div> <button onClick={() => setCount(count + 1)}>Increment</button> <Person identity={einstein} /> </div> ); } ReactDOM.render( <App />, document.getElementById('container') ); The `<Person />` component will redraw on each `increment`. Nothing changed. Why would it redraw? Because when the `App` component redraws, the `einstein` variable points to a new reference. React sees this as a change and redraws both `App` and `Person`. What looks like normal JavaScript here is not. To prevent this redraw, you have to opt out like this: const einstein = useMemo(() => ({ firstName: "Albert", lastName: "Einstein" }), []); Or know to move the reference outside of the `App` like this: const einstein = { firstName: "Albert", lastName: "Einstein" }; function App (props) { ... } Which is fine in this case because there are no dependencies on the component tree. This is the most common mistake I see in React that leads to bugs. It's not just objects, but also functions. This is also a redraw: const { useState } = React; function Logger(props) { console.log('Render Log') return (<button onClick={props.onClick}>Log</button>); } function App (props) { console.log('Render Hello'); const [count, setCount] = useState(0); const logConsole = () => console.log("HELLO, WORLD"); return ( <div> <button onClick={() => setCount(count + 1)}>Increment</button> <Logger onClick={logConsole} /> </div> ); } ReactDOM.render( <App />, document.getElementById('container') ); Why? Because on increment, the `logConsole` is a reference to a new function. So the `Logger` redraws as well. So here, you need to opt out once again by using `useCallback` or moving the function out of the component tree (fine in this case since there are no dependencies). The thing is that it looks like normal JavaScript but the React render cycle is the unseen; you have to be aware of moving things "out of the way" and "bringing them back" via a hook. React's render cycle re-evaluates entire component sub-trees for changes and if your component doesn't explicitly opt-out by preserving referential equality (`useState`, `useCallback`, `useMemo`, etc.), you'll trigger a redraw downstream. These hooks effectively move the references out of the component tree and pull them back in when the tree re-renders and thus preserve referential equality. So what teams might do is after experiencing this one time chasing down a bug is wrap every single declaration in a hook to reduce the mental burden. This then creates other issues like performance and memory. Vue, for example, is the opposite because it has fine-grained reactivity. Nothing redraws until you opt in by using the Vue reactivity primitives.
- lacrimacida 3y agoGot it. Thanks for the thorough explanation
- CharlieDigital 3y agoYou bet. But if you grok that simple example, you can see why teams that switch to Svelte, Solid, Preact, or Vue feel "refreshed". This mental burden of trying to figure out what has to be put where just...goes away. The React model tries to bend JavaScript to conform to it's render cycle rather than designing to JavaScript's unique object-functional strengths.
- lacrimacida 3y agoThanks. A while ago I sensed the churn dangerzone around React and I refused to get on any React projects. I feel lucky that I had that option. I did some Angular projects (i think it was version 8-9) and to me it seemed okay at the time. The project evolved nicely and structurally it organized itself quite well. But there is a ton of boiler plate there as well and I’d avoid Angular in the future. Im doing mostly back-end work these days to keep my sanity.
- deleted 3y ago[deleted]
- ttfkam 3y agoAfter all this time, React's sheer tonnage of boilerplate still astonishes me. That abstraction leaks like useMemo(…) even need to exist in the first place… Folks want to solve their own problems, but they keep getting saddled with React's as well.
- CharlieDigital 3y agoEvan You (creator of Vue) had a great quote on this: > The pain and suffering of hooks all roots from the mismatch between a dogmatic belief in the superiority of immutability and the harsh reality of the host language that is JavaScript (Feb 25, 2023) This fundamental misalignment with React and JavaScript is the billion dollar mistake.
- bnt 3y agoBasically avoiding the mistake Angular made (moving from 1.x to 2+)
- jzig 3y agoAnd yet Angular is now the less complicated framework and easier to work with (IMO).
- jmondi 3y agoIf Angular wasnt based on RXJS, I would agree with you that the defined structure of Angular makes it nice and predictable. RXJS pipe hell is a hell I wouldnt want to send my worst enemies to.
- mickael-kerjean 3y agoWell I absolutly love rxjs, in my opinion it's one of the very few library in the JS ecosystem that are actually worth their weight
- ttfkam 3y agoWhile RXJS definitely still has a role in the Angular ecosystem, a lot of what RXJS used to do is being handled by signals in the newest versions.
- atomicfiredoll 3y agoI admire parts of Angular's vision and think there are patterns where it shines, but it's never quite felt like they actually hit 2.0 to me. I haven't worked with it in a few versions, but I think it's just a different set of complexities. There's always some big or missing thing right around the corner... reworking Material components for years, reworking internationalization, improvements to reactive forms, zoneless Angular, single file components, etc. And, for as many bugs as they fight down, it's always felt like there were several obvious frustrations waiting to be fixed. It's all just left me with an impression that the team bit off more than they could chew in creating such a holistic solution and can't quite get to something solid, hence the need to shed things like Protractor. Hopefully the cumulative effort to improve gets them somewhere and helps get Angular into a more complete and compelling place for folks.