11 ms·
IMO if you need a long doc like this pointing out the sharp edges, then I think you've done a poor job in designing the framework. I love the terseness, reusab
by billllll 4y ago
IMO if you need a long doc like this pointing out the sharp edges, then I think you've done a poor job in designing the framework.
I love the terseness, reusability, and typing of React hooks, but hooks have too many weird edge cases (this article, dependency list, order of hooks, etc) versus class components, whose design was simple and elegant.
I'm just an old man yelling at clouds though, the terseness of stateful components defined in a function, plus simple typing with TS (no defining proptypes) is too appealing to me personally. Maybe I'll check out Solid next time, which seems to have less weird edge cases.
- junon 4y agoI've used Surplus for years and love it. Highly underrated framework. It's hooks, but designed properly, and consistently beats out almost all other frameworks performance-wise. It's in need of a few upgrades though, namely a few edge cases in the old JSX parser (it was written before Acorn had good JSX support) but works pretty much perfectly still today.
- ihateolives 4y ago> It's hooks, but designed properly, and consistently beats out almost all other frameworks performance-wise. Performance is nowadays one of my last concerns with frameworks. They're all snappy enough except for corner cases. More important is whether there are standard ways of doing things vs everyone inventing their own. Our company uses Vue which has standard lifecycle methods, standard way of scoping CSS etc, officially endordsed store etc. Makes it much easier to bring people up to date when they're joining the projects.
- bowsamic 4y agoReally it is quite an amazing situation. The conceptually clunky but easy to understand class components vs the conceptually pure but esoteric hooks. Even at the time the React dev team were putting in a lot of effort to say "you will get it soon, don't worry", because they already knew it was in many cases difficult to understand and use properly. That should have already been enough of a sign to not push it so hard.
- orangepanda 4y agouseEffect was designed to allow shooting yourself in the foot, in a good way. There's never a situation when react doesnt allow you to accomplish something - the page even a mentions of synchronising with jquery! Whats the alternative you propose? Not allowing react to be used with any 3rd party libraries or access to browser apis?
- justusw 4y agoSorry for the disgruntled snark in advance: Heh, we already have that and it is called Elm. By me, an Elm user until 0.18.
- Kimitri 4y agoYeah, it's a right pain to deal with non-Elm things in Elm (including JSON data sources). It's possible but you will want to avoid it. However, I think I'd still take Elm over React if I didn't have to care about anyone else but myself.
- rawoke083600 4y ago>useEffect was designed to allow shooting yourself in the foot, in a good way. Ok... no... there is no good way to shoot yourself in the foot (metaphorically or real) >There's never a situation when react doesnt allow you to do something That is EXACTLY what I DONT want from my framework:
- foldr 4y ago[allow shooting yourself in the foot] in a good way
- ohgodplsno 4y ago>That is EXACTLY what I DONT want from my framework: Unless you're happy about never going out of the guardrails set by your framework, there's going to come a point where, one way or another, you're going to need to interact with something outside of it. Are you going to wait for an official React-WASM way to interact with WASM (which is going to be using useEffect under the hood anyways)? Frameworks with no escape hatches are hell. The escape hatch just needs to be bright, bold and with a warning on it that says "there can be demons behind that hatch, watch out".
- rawoke083600 4y ago>IMO if you need a long doc like this pointing out the sharp edges, then I think you've done a poor job in designing the framework. x1000 upvotes. One alternative is of course svelte, the unofficial-slogan (svelte) is/was that you can explain it to someone or learn it yourself in an afternoon. Reminds me a lot of C++ vs Go in terms of Public/Private/XYZ Go: To make a something public, start the var name with uppercase. C++: To make things public read the Chapter on "Access Modifiers".
- DavidPiper 4y agoWhile I agree with your point, the example you gave feels like a straw man. Or at least, a separation of "sharp edges" and "long documentation needed". Phrased differently: Go: To make a something public, start the var name with uppercase. C++: To make things public, type the word 'public'. The Go pattern seems like more of a sharp edge than the C++ version, even though the C++ version might need more reading to learn.
- the_gipsy 4y agoGo using casing for access is quick but is awful when you just want to change the access later on. It's not like writing `pub` before the var/field is suddenly javaland, see rust.
- aatd86 4y agoWhat do you mean changing the access? You mean from private to public? In that case, you would just have to change a single package. (also, if yes: does it happen often and is that really what we should optimize for then?)
- the_gipsy 4y agoYes, you have to rename a var/field to change public/private. It's not a huge deal of course, just an annoying exception. Re: optimization, what does using casing instead of an explicit `pub` prefix optimize for, exactly? Compiler complexity? Typing ergonomics?
- rozenmd 4y agoNot all sharp edges are equal, the sharpest (according to % of traffic to my blog, anyway) seems to be race conditions (https://maxrozen.com/race-conditions-fetching-data-react-with-useeffect https://maxrozen.com/race-conditions-fetching-data-react-wit...), and that's not even unique to useEffect...
- kristopolous 4y agoI've run into race conditions inside of react that has made me gobsmacked. I swear the thing must be written by fresh faced middle schoolers. I'm so glad I don't have to deal with it anymore. After being in programming for over 20 years, I started making plans to exit the entire industry. Now I realize it was just react. That thing made me despise programming. I kept a virulent twitter journal of my time in react. It seems foreign to me now. Good! Example(s): https://twitter.com/SisNode/status/1458942812087414797 https://twitter.com/SisNode/status/1458942812087414797 ... it made me pretty intolerant https://mobile.twitter.com/SisNode/status/1433809323948273666 https://mobile.twitter.com/SisNode/status/143380932394827366... The tweets in that account are like an insult comic does programming.
- doodlesdev 4y agoI think I just found a reason to use Twitter. This might be the best Twitter account I've ever seen lmao.
- kristopolous 4y agohey thanks. I know there's always many actual people behind all these projects trying their hardest. I hope nobody takes my jeers personally. I'm playing a character. I mean sure, the passions are real but I'm also ostensibly a well behaved sincere adult. I don't actually want to "literally stab the people who wrote [apache modrewrite] repeatedly in the eyeballs" - although a reconsideration of how transparent the flow is would be greatly appreciated. Perhaps I should add that to my list of "things to do" and you know, fix it myself. Be responsible or something. I've become intentionally unemployed in order to spend some time on stuff like this and regroup. I should do it. Honestly, I'm probably still recovering from that react project. Maybe I should do some therapy. It was bad.
- agumonkey 4y agoThere's a running in circle feel about react right now for me. It's the same old OO (state+methods) vs FP (lexical scope + closures) thing, in the dom now. A lot of react state libs are also tweaking around this idea. Not long ago a jotai class made me see this. <Component /> <Component /> these components use the same state defined in the source so to avoid that <Provider> <Component /> <Provider> <Component /> which now intercepts the state object creation to have two independent states. I have a feeling that soon we'll see <new class={Component} /> strange
- wouldbecouldbe 4y agoIMO the simple old class & props was all that was needed. Lifecycle was much easier to understand, most reusability issues could be solved one way or another. Most bugs I find in big react projects are either by using multiple useEffects in one component, and the other one with Saga. Also another "side effect" tool.
- chrisweekly 4y agoClass component usage patterns where "lifecycle was much easier to understand" were inherently problematic though; they led to redundancy and verbosity, grouping unrelated code in a given lifecycle method and fragmenting otherwise-related code across disparate methods. Those deprecated lifecycle methods are overly imperative, with poor ergonomics. (Dan Abramov wrote a great post about these shortcomings; I'm on my phone or I'd try harder to dig up the bookmark). Don't get me wrong, I have fond memories of using classes as bags of methods (esp with Mobx) and it took me a while to come around on hooks. But given your "most bugs... useEffect... and Saga" (does anyone still use Saga?), maybe the over/misuse of useEffect -- not hooks / FC more generally -- is the crux of the problems you've encountered. Which might even reinforce the OP (shrug). :)
- Sammi 4y agoThose are tradeoffs. Lifecycle methods had pros and cons. Hooks have other pros and cons. Lifecycle methods had the right pros and cons for most devs. Hooks are horrible for new devs, as they have to many gotchas, and there far too many people that just don't have the time to learn all the footguns of hooks. So lifecycle methods had some other drawback? Yes, sure, but they were less than the drawbacks of hooks for most people.
- chrisweekly 4y agoWe're agreed that nearly everything has pros and cons. But these confident assertions about what's "right" or "horrible" are subjective, personal preferences. And unsubstantiated claims that they apply to "most devs" or "most people" is merely a projection. That contradicts my direct experience (I've never encountered a single team that adopted hooks and went back). Hooks' adoption rate (along w React's market share) suggest I'm not an outlier. All that said, I'm glad TMTOWTDI. I also want to pause and thank you for sharing your perspective; dissent is valuable and helps prevent groupthink. Have a great day!
- davedx 4y agoNo you're right, I completely agree with you. It's also very telling that there's also this very long article about useEffect dependencies: https://react.dev/learn/removing-effect-dependencies https://react.dev/learn/removing-effect-dependencies useEffect and dependencies are the worst part of React at the moment. The reason is, you do need to use effects, everywhere in your code, constantly. And dependencies, and the linter rule that goes with them, are nasty ergonomics, and hard to reason about. The article I linked does explain it all quite well, and most devs I work with do understand the dependencies rules, but the rule still needs to be disabled often. Why? Often the lint errors really are just wrong. Just like ChatGPT is often simply just wrong, no ifs or buts. For example: you have a callback function declared as an expression, that the useEffect hook calls. The linter will say "oh this is an expression, therefore it needs to be declared as a dependency". But it doesn't, because looking at the code as a human, you can immediately see the function never changes. If you follow the linter, you will inevitably end up going down a destructive and unnecessary refactoring. You'll end up with unnecessary `useCallbacks` sprinkled everywhere that hurt readability for nothing. Often, you'll have to refactor the dependencies out of the component entirely, splitting one cohesive component into two, just to satisfy the linter out of an abundance of caution. Junior devs will be confused. Senior devs will be frustrated. Every react codebase I've worked on has gagged this linter warning. So how should this work? It shouldn't be a a linter error in the first place. Linters should be used to enforce coding standards, not fix application bugs. I feel very strongly on this.
- zarzavat 4y agoThe funny thing is that React already kind of has its own programming language: JSX. If they wanted to, they could add language features to support React. I expect that would be very controversial though.
- yencabulator 4y agoSvelte is pretty pleasant, compared to React. It's fundamentally a JS-to-JS compiler that adds reactive assignments, and ridiculously much more usable than useEffectHopeThisWasTheRightThing. let count = 1; // this is reactive $: doubled = count * 2; function handleClick() { count += 1; }
- ly3xqhl8g9 4y agoReading sentences such as 'Effects are an escape hatch from the React paradigm.' in the official documentation in 2023 while writing React since 2015 makes one depressed and angry (deprangry?): then how are you supposed to use this 'library'. Luckily they provide a firstName/lastName example, because that's all we use React for, no?, login forms and hello world todos apps. As with everything, if you want to make an apple pie, make a universe: after all, the mistake was mine, starting to use React in 2015 instead of making my own language/framework, mainly because what I have today is already a bunch of highly idiosyncratic React utilities. If there is one hope with the large language models hype is to finally be able to code against a true common interface (the HTML/CSS/JS specification), and do it anyway you please, translating on the fly any third-party dependency.
- threatofrain 4y agoBe warned that the state of docs is very weak, and that although the Solid team acknowledges this issue and are working on a beta¹ version of the docs, the effort really crawls along. It's also really hard to get help. Maybe there are many Solid lovers, but there aren't enough Solid intermediates to help prune the support forum. I attribute this to slow progress of the docs. [1]: Note that this docs effort doesn't include SolidStart, which is a big bummer.
- cbovis 4y agoI actually disagree here pretty heavily and think that this doc is due to the bar for competent developers going down in recent years (due to the rise in necessity for more developers of course). There's almost an expectation that powerful tooling should be dumbed down. The entire doc is written around two common problems: * You don’t need Effects to transform data for rendering * You don’t need Effects to handle user events Both of these problems do not occur if you take the time to understand the tooling React gives you. The events point should be a given, that's just React 101 (and yet they have to spell it out to people...). You don't end up using useEffect to transform props/state and generate new state if you understand that those things are just variables and you can instantiate new variables using them inside the scope of the component function. "But that's inefficient because of how re-rendering works". Great, you understand how re-rendering works but haven't gotten familiar with the useMemo hook. Come back when you've gotten familiar with the primitives available to you in React and how they can all work together in different ways, there's not that many of them! This doc reads to me like a DIY store publishing an article about how you shouldn't hammer in screws even if it kinda seems like you could if you didn't take the time to understand hammers, screws, and nails. It's sad that it needs to exist but that's the current state of engineering.
- Sammi 4y agoI have no idea what you just said :/ But I barely know React.
- _heimdall 4y agoYour entire argument here is a shining example of how the growing complexity of react has raised the bar of skill for competence rather than being a victim of lowering the bar. Think back to the webdev world before react. Was it really that the average dev was more competent, or that the tools of the day were in fact more simple to use? Sure there are more and less efficient ways to use jquery, but unlike react you didn't have to keep so much in your head at once while building a simple feature. React was designed to be a UI component library. We keeping asking more of it and stuffing more and more complexity into react so that monolithic frameworks can be built with it. It was never designed with that goal in mind and is taking more and more complex features to try to keep that ship afloat.
- gspencley 4y agoPart of the problem is that React was never a "framework" to begin with, but people treat it as if it is. React began its life as a view library for creating custom components. That initial design decision has permeated every attempt to make it more "framework-like." In a traditional MVC-like paradigm, components would just be views. Discussions would be focused around keeping your components limited to view concerns while using other, non-view parts of the framework to drive things like API integration, business logic, state management, routing config and so on. Which is to say that you wouldn't have a need for "effects" at the component level in the first place since, by the time your data is ready for presentation and your components are initialized, all of that has already been done separately. So yes, it is a design flaw with the "framework". One that came about by trying to morph what was, initially, a simple view library into something more "framework-like."
- KronisLV 4y ago> I love the terseness, reusability, and typing of React hooks, but hooks have too many weird edge cases (this article, dependency list, order of hooks, etc) versus class components, whose design was simple and elegant. You know, I kind of agree and personally prefer Vue (that does hooks better in some ways, as well as has a simple store solution called Pinia that's nice to use), but I have to say that these docs themselves are great. Even if there is some awkwardness about using React and it needs some getting used to, to be able to use it effectively, I think these docs are definitely a step in the right direction and offer concrete examples! The code is mostly clear, the text explains everything bit by bit - we could use more of that in our industry for sure.
- ttfkam 4y agoIt's a sad state of things where React—even with hooks—is considered by some developers as "terse". It makes me wonder if we're all actually speaking the same language.
- vbezhenar 4y agoOne thing that I don't understand: why design useEffect api with dependencies array which does not get passed in the function? If you ask me, I'd design it the following way: useEffect(f, {a, b, c}); ... function f({a, b, c}) { ... } Function f is supposed to be declared outside of render function. This way you must specify all the dependencies. JavaScript will bite you with undefined value, TypeScript will bite you with compilation error. The drawback is that you'd need to pass setValue functions which are typically immutable, but I don't think that's a bad thing anyway.
- pavlov 4y ago> "Function f is supposed to be declared outside of render function." That's the cinch. To get the benefit of this proposed API design, the effect handler functions must be be outside of the render function so they can't capture any values other than the explicit dependencies. That's not a requirement you can enforce in JavaScript, so it would have to be a linter-level thing. I think it would aesthetically run counter to the prevailing design of React functional components. For better and worse, it feels like the framework designers have made a substantial effort to contain a component inside a single function. With this design, you'd have the component and its effect handlers in the same parent scope even though the handlers are subordinate to the component.
- rk06 4y agoHow would useEffect () access those dependencies? useEffect() them to determine if f() needs to run again or not.
- slmjkdbtl 4y agoSolid has very similar API, but much simpler concept (and of course performance), it's just a plain js signal library with some ui helper functions no dark magic, whereas react is the most framework framework out there.
- mpweiher 4y ago> IMO if you need a long doc like this pointing out the sharp edges, then I think you've done a poor job in designing the framework And it seems that the React maintainers don't understand their own system, in a sense. That obviously sounds a bit weird, but as far as I can tell they seem to think that what makes React good is that it is "functional". And so when something isn't quite right, they "fix" it by making things more functional. And that seems to invariably make things worse. Rinse and repeat. Hmmm... What if the good part of React is that it is a reasonably decent UI widget framework for the web? And that the FP-ish nature is really more an implementation detail due to the way it is embedded into the web platform? And that this led to the happy accident of being able to write the UI as a procedure that structurally reflects the UI to be displayed?
- rglover 4y ago> IMO if you need a long doc like this pointing out the sharp edges, then I think you've done a poor job in designing the framework. Thank you. It's self-serving (mea culpa), but this is the exact reason I moved away from React and decided to build Joystick [1]. [1] https://github.com/cheatcode/joystick https://github.com/cheatcode/joystick
- schwartzworld 4y agoThe problem is that React was designed to allow you to use functional programming to express a UI that is a function of state. It might be obvious to experienced functional programmers not to sync internal state using effects in this way, in no small part because they understand what a side effect is already. > dependency list This, again, is only confusing if you don't understand what an effect is for: syncing with systems external to React. How else would you say "do the thing when any of these change"? > order of hooks I never understood why this was confusing for people. It takes 2 seconds to learn this rule, and your browser console will yell at you if you violate it.
- oaxacaoaxaca 4y agoCompletely agree. Class components are so beautifully simple. Hooks have infuriating edge cases and are so bizarre they need ESLint plugins to remind people how they work.
- klysm 4y agoI don’t see why productive frameworks must be obvious. Once you learn how to think in functional react, it’s a very productive framework that enables you to bang out applications
- ttfkam 4y agoThere is nothing in React I'd regard as "terse". Perhaps slightly more terse than the mountain of boilerplate it required previously, but that's as far as I'd go. https://youtu.be/AdNJ3fydeao?t=702 https://youtu.be/AdNJ3fydeao?t=702 We really should accept that all of the following are ABSTRACTION LEAKS and not inherent benefits to web development at large: • shouldComponentUpdate • React.PureComponent • useMemo • useCallback • Concurrent mode They exist solely because React's underlying model is insufficient and we, the developers, are being made to do the computer's job with all this optimization boilerplate. The VDOM is dying. Let it die. It's long past time to move on. Any further React development in the existing foundation is just continuing to build upon sand.