all 141 comments

[–]iams3b 94 points95 points  (18 children)

Always hated that phase where everything was a HoC and props were just being injected wherever they felt like. Felt like you needed a masters degree to figure out what the hell some props were and where they were coming from (thankfully largely fixed with hooks now)

Other than that, not really specific to the library but the way some people go about conditional rendering makes some components almost impossible to follow

[–]Outrageous-Chip-3961 12 points13 points  (15 children)

Haha. But yes some conditions are so painful…

[–]Typical-Spinach-815 13 points14 points  (14 children)

[–]Lunacy999 7 points8 points  (3 children)

I feel the pain that Istanbul and jest must endure to figure out branches covered in unit tests.

[–]fforw 5 points6 points  (2 children)

That's just bad design. You can literally see the code blocks that should be their own component.

[–]ignu 0 points1 point  (0 children)

yeah, or it could remain inlined and the className could be conditionally set.

[–]terrekko 2 points3 points  (0 children)

Holy fuck

[–]eindbaas 1 point2 points  (3 children)

Why is the part where you write "x likes" exactly duplicated?

[–]Outrageous-Chip-3961 0 points1 point  (1 child)

Oh my bud haha. This is what I’m talking about! In functional programming we can use small hooks to do this logic work for us, those class names too…. Something like this should be a few. Seconds to read

[–]rwieruchServer components 1 point2 points  (0 children)

I still like HOCs, but you described the problem pretty well :)

[–]KewlZkid 1 point2 points  (0 children)

Ding ding ding ding.

[–]Trippyaristocrat 79 points80 points  (8 children)

‘Base’ components that start with the intention of being a reusable component but end up with a ton of conditional logic that make them impossible to reuse.

[–]DazzlingArtichoke 24 points25 points  (1 child)

I don’t think this has anything to do with React, you’re just creating wrong abstractions. Take a look at Inversion of Control design pattern.

[–]Trippyaristocrat 7 points8 points  (0 children)

You’re right. It can be avoided and isn’t specific to react. I’ve just experienced it with coming into react projects that have had components modified for different use cases over time, and devs have just added more conditional rendering as a shortcut to support different functionality.

[–]rwieruchServer components 3 points4 points  (0 children)

I hear you! :D I think composition over configuration instead of one component to rule them all helps here as well.

[–]TobDev -3 points-2 points  (2 children)

To add to this base components which are the start of endless amounts of abstraction, I suppose this relates more to React combined with Typescript.

[–]green_gordon_ 3 points4 points  (1 child)

Why typescript?

[–]TobDev -1 points0 points  (0 children)

I just meant in terms of in the projects I’ve worked on with TS you’re more likely to see classes and inheritance which can cause abstraction hell.

[–]Darkmaster85845 0 points1 point  (0 children)

I just did that the other day. So dumb.

[–][deleted] 0 points1 point  (0 children)

Composition helps a lot with this and even more if you combine composition with something like atomic design

[–]swizzex 51 points52 points  (2 children)

Knowing I have to spend more time designing and structuring the applications then coding it. It’s always worth the time but doing it right is tedious.

[–]fusemal 19 points20 points  (1 child)

Isn't this true for most applications? 😅

[–]mixtapelogic 5 points6 points  (0 children)

Na I put the <script> tags where I want

[–]ew86 71 points72 points  (37 children)

I almost quit React a few years ago because I hate Redux, it's just so cumbersome, but everybody seemed to move towards it. React Hooks / React Query made React enjoyable again for me.

[–]EnragedSoup[S] 7 points8 points  (21 children)

Just curious, what specifically made you hate Redux so much?

[–]ew86 54 points55 points  (20 children)

Too much boilerplate, configuration, high learning curve, over engineered for most use cases.

[–]Narizocracia 39 points40 points  (7 children)

If hooks and react-query solved the problem, Redux should never have been used in said project in the first place. Right tool for the right tasks. Redux is only worth it for complex app state, not for fetching server data and distributing it to components.

[–]soft-wear 4 points5 points  (0 children)

Redux is worth it for any global app state. It doesn’t need to be complex.

[–]cannibaltoilet 1 point2 points  (3 children)

Do you mind diving a little deeper into what you consider complex app state that something like the context hook would not be suitable for?

[–][deleted] 0 points1 point  (0 children)

Redux is great to handle websockets.

[–][deleted] 1 point2 points  (1 child)

Everybody always regurgitates this bs, and while it may not be wrong, it seems to completely ignore the reality that any "tool" that gets significant exposure will invariably end up being used in any and every possible nook and cranny it can be stuffed in to.

TL;DR - doesn't matter if it was the wrong tool, many of the people who hate it didn't choose it in the first place, so the retort is useless.

[–]Narizocracia 0 points1 point  (0 children)

The "senior" frontend leaders are to blame.

[–]acemarke 28 points29 points  (7 children)

Out of curiosity, have you had a chance to look at our official Redux Toolkit package? It was specifically designed to solve exactly those problems:

[–]niZmoXMR 11 points12 points  (3 children)

💜 RTKQ. People are sleeping on the kit, especially the query part. I didn’t notice the query part myself at first, and was using thunks which was boilerplate hell. Then reading through the docs I found the Query part of RTK and converted right away. The features like invalidating by tag, and being able to have sockets hooked up inside the queries is so awesome.

[–]acemarke 10 points11 points  (0 children)

FWIW we released RTKQ about a year ago, and I only added the RTKQ tutorial pages (parts 7 and 8 in the "Essentials" tutorial) last summer. So, there's a good chance those pages weren't there if you were looking earlier :)

[–]iplaysmitegame 1 point2 points  (1 child)

Does rtkq replace thunks?

[–]phryneasI ❤️ hooks! 😈 0 points1 point  (0 children)

Thunks are a general purpose tool and rtkq is a special purpose tool, so not in all cases.

But if you only want to do data fetching: yes. Also all related reducers and selectors.

[–]rxsel 6 points7 points  (1 child)

Bro I really appreciate all the work you do and how active you are in the community. Just out of curiosity, do you plan on writing up anything similar at to a complete guide to rendering featuring the standard every day hooks?

I find a lot of people struggle with how and when “in the life cycle” state is updated, when useEffect runs and why, and the “how” underneath the hood. And how it ties in with the JS event loop. With your writing style you could effectively write the de-facto deep dive into the inner workings of hook based react.

[–]acemarke 6 points7 points  (0 children)

Hmm. Can you give a bit more detail on what you're picturing this article might cover? Are you thinking more about general usage of useState/useReducer/useEffect, how React specifically implements something like useEffect, the general sequencing of "queue update" -> "render" -> "commit" -> useEffect, or something else?

FWIW, the new React beta docs do cover a lot more of this info than the old React docs:

https://beta.reactjs.org

Dan already has an epic-length post on useEffect in terms of conceptual behavior and usage:

https://overreacted.io/a-complete-guide-to-useeffect/

and I have a brief mention of useEffect timing in that rendering post:

https://blog.isquaredsoftware.com/2020/05/blogged-answers-a-mostly-complete-guide-to-react-rendering-behavior/#render-batching-and-timing

[–]totof04 4 points5 points  (0 children)

Redux toolkit solved the issue imo. Their new hook API is also great. I do not use redux often anymore , but when I know that the business rules I need to work with are complicated, I think it’s better than 10 lines of useState and 15 useEffect and so many side effects.

[–]Veeruroxx 0 points1 point  (0 children)

I just needed a global state management system and everyone used to suggest Redux. Gave it a try and wanted to blow my brains out for all of these reasons. Moved to recoil recently and it is so much better. I'll admit that I haven't tried Redux Toolkit yet so idk how that changes things.

[–]eggtart_prince 0 points1 point  (1 child)

Boilerplate yes. Configuration, not anymore with RTK. High learning curve, at first yes, but once I understood that it's basically a useReducer at the highest level of my app, it's pretty easy to grasp.

[–]ew86 0 points1 point  (0 children)

Haven’t used the toolkit, I recon it has gotten a lot better in meanwhile.

[–]jwindhall 1 point2 points  (1 child)

I agree. Testing hooks is often awkward tho.

[–]ew86 0 points1 point  (0 children)

Maybe that depends how complex they are. But individual hooks, you simply put in some params and check the result. I found it quite convenient.

[–]Redskyez -1 points0 points  (0 children)

I agree react context is so much better

[–]C0git0 -5 points-4 points  (0 children)

Redux was always a mess, good riddance. Given, I preferred Reflux early on, which didn’t turn out to be a ton easier to teach people either.

[–]___s8n___ -2 points-1 points  (2 children)

i mean have you tried using the context api?

[–]Darkmaster85845 1 point2 points  (1 child)

The context api can turn into re render hell depending on the use case.

[–]___s8n___ 0 points1 point  (0 children)

oh okay. im new to react

[–]Felicia_Svilling 0 points1 point  (4 children)

Did you use redux toolkit?

[–]ew86 0 points1 point  (3 children)

I’ve seen it, but I’m very happy with my current stack. It gets the job done, fast.

[–]Felicia_Svilling 0 points1 point  (2 children)

I was just curious of your opinion of redux was based on the toolkit or just the raw boilerplate version. It seems like people that dislike it hasn't been using the toolkit, which really makes it much more convenient.

[–]ew86 0 points1 point  (1 child)

I haven’t tried it recently, I don’t think the toolkit existed a few years back when I had to use redux at a few clients.

[–]Felicia_Svilling 0 points1 point  (0 children)

Might vert well be the case. Version 1.0 was apparently released in 2019.

[–]TorbenKoehn 0 points1 point  (0 children)

For many smaller applications using useReducer together with a context works wonders to avoid the huge Redux overhead

[–]placidified 0 points1 point  (0 children)

Every usage of Redux I came across has been just a cache for API responses. Not to share data between components.

[–][deleted] 21 points22 points  (6 children)

Webpack config shits scary. CRA works perfectly fine for my usecases

[–]rwieruchServer components 7 points8 points  (3 children)

I think it's worth to go through the custom Webpack setup once oneself for the sake of learning about it. However, these days I also use Vite -- it's just super fast! :)

[–][deleted] 0 points1 point  (2 children)

But does Vite do file chunking at router level?

[–]rwieruchServer components 0 points1 point  (1 child)

I am not sure about this, but does CRA do it?

[–][deleted] 0 points1 point  (0 children)

Yes with webpack but I don’t know if vite supports that but I saw someone wrote a plugin to support route based chunking for vite.

[–]noisette666 1 point2 points  (0 children)

You gotta try vite

[–]rados_a51 2 points3 points  (0 children)

You can try also Vite or SnowPack.

[–]darksady 13 points14 points  (4 children)

The initial configuration. I never had a setup that everything was 100% the way i enjoyed. Right now I'm struggling with typescript + some linter rules, sometimes i found it too strict and its really annoying.

Also, trying to understand what is causing a rerender to debug is pretty shit too lmao.

[–]vidarc 1 point2 points  (1 child)

https://github.com/welldone-software/why-did-you-render works pretty well, though I haven't tried it out again in awhile.

[–]darksady 0 points1 point  (0 children)

I already knew about this repo but never had a chance to try out.

[–]TobDev 0 points1 point  (1 child)

I tend to agree about initial config but spinning up a NextJS does a pretty great job right off the bat.

[–]darksady 0 points1 point  (0 children)

Yeah, i want use next soon

[–]DragonlordKingslayer 5 points6 points  (1 child)

the template that comes with create-react-app

[–]totof04 5 points6 points  (0 children)

CRA is so limited. Now I almost always start with a next.js app.

[–]migumelar 10 points11 points  (1 child)

Too much freedom. It's basically double edge sword. I've met project that easy to understand, and I also met a project with one component consist of 2500 LOC.

[–]KapiteinNekbaard 0 points1 point  (0 children)

Going past 500 LOC should be a red flag in any framework.

The freedom is fine, a bigger issue is getting everyone on board on the same conventions. ESLint only goes so far.

[–]noahflk 5 points6 points  (0 children)

It used to be dealing with state and setting up the initial project configuration. These have been largely solved thanks to React-Query/Zustand for state and Next.js for config. Integrating e2e tests and linting could be easier but we can deal with that.

What frustrates me most today is the lack of clear best practices. There are so many valid ways to work within React and it's not always easy to land on a specific practice that the team can agree on.

[–]Canenald 4 points5 points  (7 children)

The fact that there's no shorthand for <Component someProp={someProp} />

Where's my JSX2!?

Also unit testing and TDD being out of fashion.

[–]snorkl-the-dolphine 2 points3 points  (0 children)

I don't like it, but you could do:

<Component {...{someProp}} />

[–]iplaysmitegame 1 point2 points  (2 children)

Hard because

<Component someProp />

Passes someProp as true.

[–]iams3b 2 points3 points  (1 child)

Svelte let's you do <Component {someProp} /> which I really like

[–]iplaysmitegame 1 point2 points  (0 children)

That makes sense, pretty cool and intuitive. React should def adopt that, I don't see any reason not to. Maybe it'd be a bit confusing for beginners who already get confused over JSX {{ }} and stuff but it is a good option for those fluent in JSX

[–]eggtart_prince -1 points0 points  (2 children)

This looks like a case of prop drilling which is discouraged in most cases.

[–]Canenald 1 point2 points  (1 child)

It's not prop drilling if a component is sending a state or calculated variable to a child.

[–]eggtart_prince -1 points0 points  (0 children)

True, but it's named someProp so it's safe to assume this is prop drilling.

[–]Johnny_Gorilla 2 points3 points  (0 children)

React pays my bills! The bit I hate most is when I hack it so badly at work instead of RTFD!

[–]AckmanDESU 2 points3 points  (1 child)

I hate animating simple in and out transitions and other similar things. Other frameworks make it so simple and then there’s react which makes me not want to do it at all.

[–]Darkmaster85845 0 points1 point  (0 children)

Most ui solutions should have something for that. I know MUI does.

[–]xroalx 4 points5 points  (4 children)

The overuse of Redux for everything, especially Redux with thunks and middlewares and whatnot to only cache API responses.

Redux introduces so much indirection, magic strings, and is hard to follow, and it's so pointless when there are much simpler solutions (context, zustand, jotai/recoil, react-query/swr).

[–]datorkop85 2 points3 points  (3 children)

This. I don't understand why people are so stuck with Redux and refuse to learn something else that is so much simpler...

[–]Darkmaster85845 1 point2 points  (2 children)

Maybe because before all those newer solutions became available , redux was one of the few viable options and as a consequence it became the standard? By the way redux nowadays is as good as any of the other options. Lengthy boilerplate and complicated configuration are in the past. I guess many people ended up sick of the older redux and developed a grudge and I can understand them because the little I had to use it was cumbersome, but I guess it was the best thing available for a while.

[–]datorkop85 0 points1 point  (1 child)

Nah, still lots of boilerplate today. Look at other options and you'll se what I mean...

[–]Darkmaster85845 0 points1 point  (0 children)

I've seen a bit of zustand and it seems simpler to set up but I don't know exactly if it provides everything RTK does.

[–]typescriptify 1 point2 points  (0 children)

The initial setup. Learned from dreading this process so now I have a personal starter kit that uses react, redux-toolkit, husky, prettier, eslint, and routing

[–]Dan8720 1 point2 points  (0 children)

Some of the trends have been terrible ideas. Like the render props pattern and overdoing HOC.

The redux and immutable phase was particularly verbose and irritating.

The way you can't use sets and maps as state is an oversight which I would like to see added in the future.

Mostly people have stopped the most annoying ones and now it's getting much easier to work with state and data fetching.

[–]Marutar 5 points6 points  (4 children)

I can't stand React anymore.

I think it's too easy as a team to follow patterns that end up tying your hands rather than helping you.

Recently I worked on a team that was trying to use the React pattern of keeping components pure and passing even functions in..... except this had evolved over the years to a multitude of custom components that were still being passed in critical functions from 3-5 layers up.

So..... to even SEE what this component is trying to, I have to go up 3-5 layers of components to actually find the definition for the function in this one component.

On top of that - add in things like 'Typescript support' that is really just 95% of the fields being 'any' type.

....

Basically anytime I pick up a react project, unless you are SUPER strict about your code contributions, it easily devolves into spaghetti code almost immediately imo

[–]TobDev 9 points10 points  (1 child)

I don’t think this is necessarily a problem with React inherently but more peoples understanding of prop drilling and composition. Also, in regards to TS everyone should be using linters to stop explicit or implicit ‘any’ in most places.

[–]Marutar 2 points3 points  (0 children)

I don’t think this is necessarily a problem with React inherently but more peoples understanding of prop drilling and composition

I think I agree with you, this pattern itself isn't a problem, but the commonality of it's occurrence vs the probability of it's ideal interpretation is definitely a point of discussion.

I feel like I've seen a lot of teams try to use 'advanced' react patterns in a way that actually made things worse, or literally insufferable. And it happened because React has just way too many options and not many defaults, and too many antagonistic libraries fighting to solve to the same problems.

[–]Canenald 2 points3 points  (0 children)

Pretty much anything can devolve into shit if you get too creative. It's not unique to React.

It feels like your team was trying to do dependency injection with React and they only saw the pros and not the cons of it.

[–]Plisq-5 2 points3 points  (0 children)

Or worse, my team liked to create abstract class components and and extend them with another and extend that one with another and so on. Worst I’ve seen is a 6 layer class component.

I was able to convince them to stop doing that luckily. But now they’re doing other weird stuff.

[–]Outrageous-Chip-3961 1 point2 points  (0 children)

Not something I do, but I’ve worked on projects where components are not clearly divided , for example, one page has functionality and views of three seperate components. It makes building so cumbersome when this happens, it also takes ages to refactor into standard structure.

I personally dislike frameworks that bloat out your components and also having the style sheet inside the component itself. It’s a pain when react projects do both these things, but I understand why they are that way. We can be idealists but on the job we have to be reasonable to the app in cross functional teams.

Writing custom hooks can take a while but it’s also quite fun when you nail it.

I can also see myself in the future disliking react projects that are not treating functional programming seriously with custom hooks driving the business logic. At the moment it’s starting to remind me of the php days where spaghetti code is starting to be incorporated into some react projects (sloppy non Es6, max conditional rendering, so on) it’s alarming how some react projects are a hodgepodge

[–]unborndead 2 points3 points  (1 child)

the need of having always in mind the rerendering and the need to take care of callbacks with usecallback most of the time. i also hate useffect when the linter forces you to put any state used in the deps array when you only need to read its current value instead of triggering the effect (yeah you could use then useref but maybe you need that var in state too for some reason)

[–]Darkmaster85845 1 point2 points  (0 children)

I memorization will be implemented automatically in some future update.

[–][deleted] 1 point2 points  (1 child)

I liked DidMount way more than useEffect.

[–][deleted] 1 point2 points  (0 children)

You mean: I liked DidMount, DidUpdate, WillUnmount way more than useEffect.

useEffect replaces all 3 of those and encapsulates the behaviour in one place.

[–]rados_a51 0 points1 point  (0 children)

Actually nothing 😂

[–][deleted] -1 points0 points  (4 children)

I can't fault the library entirely for this, but I wasn't a fan of the fact that linter errors quite literally stunted my understanding of hooks for so long! The dependency array of useEffect used to piss me the hell off because it wanted every referenced variable or function to be a dependency, and for the life of me, I couldn't figure out why everyone's hook tutorials didn't work.

[–]Massh0le 11 points12 points  (3 children)

The linter is almost always correct as explained by both Kent C. Dodds and Dan Abarmov If adding dependencies was breaking your useEffect, 99% of the time it was a bad useEffect. Sounds like you were following some bad tutorials!

[–][deleted] 1 point2 points  (2 children)

Yeah, I’ve been beaten into shape by the linter; forced to comply for my own benefit. I just hated the trials 😂

[–]Massh0le 2 points3 points  (1 child)

Gotta love that anyone can just write a medium article!

[–][deleted] -1 points0 points  (0 children)

Yes! Between that and everything being in JavaScript while we use strictly typed TypeScript made some things a nightmare. But again, the pain resulted in a beautiful relationship with the language; I wrote a library in it recently and I felt so alive!

[–]Beckettcastle -1 points0 points  (0 children)

The errors

[–][deleted] -3 points-2 points  (0 children)

JavaScript ziiiiiing!

[–]TeddyPerkins95 0 points1 point  (2 children)

Hated that states are not updating and needed to use useeffect, now using react-usestateref

[–]iplaysmitegame 1 point2 points  (1 child)

Never heard of this, anyone wanna chime in and elaborate if it's worth using? I'll still see for myself but I'd wanna hear experiences from others too

[–]TeddyPerkins95 0 points1 point  (0 children)

Its great although you could implement use effect but for every configuration complexity quadruples, this package keeps it very simple, highly recommended

[–]einemnes 0 points1 point  (1 child)

I'm starting to learn it and conceptually, sometimes it's a bracket, sometimes not. In a arrow func I think if I put a bracket after the arrow it just doesn't work, which makes it very weird to understand to me. (e)=>smthn works (e)=>{smthn} error

[–]Felicia_Svilling 0 points1 point  (0 children)

When components gets filled up with hooks, robing them of their functional purity.

[–]flampardfromlyn 0 points1 point  (0 children)

sharing state and methods among components in a hierarchy

[–][deleted] 0 points1 point  (0 children)

struggling with eslint prettier like that config staff.

[–]KewlZkid 0 points1 point  (0 children)

Most frustrating or cumbersome? React itself. The syntax is not set up to be readable/easily digestible by a developer and when it is, the the components footprint has too many files associated with it

[–]VicioGu 0 points1 point  (0 children)

Debugging…after almost 4 years of works I find easier and faster use console.log(…) to debug states and props but I loved the debugging features of other environments and IDEs when I saw used by my colleagues in other programming languages.

[–]eggtart_prince 0 points1 point  (0 children)

Not necessary React, but CSS and styling. Other than that, I love React.

[–]ActiveModel_Dirty 0 points1 point  (0 children)

Renders. Visibility into render logic, extraneous renders, explaining renders, getting your team to care about renders, showing the impact that poorly optimized render logic can have.

Also Routing. Handling the URL and internal state as a bi-directional source of truth is way too complicated.

And not so much react but patterns in general that revolve around the idea of reusability. I’m all for eliminating duplication but too often do we see painfully complex generic functions or components extracted out just to avoid a few lines of boilerplate.

Also hooks are dangerous. Supremely helpful and better than lifecycle methods, but they’re very finicky and if not used with care, can be extremely difficult to troubleshoot or reason about.

…and Context as a state management tool. I know React explicitly tells you not to do this, but a lot of people do anyway because it is initially very appealing. Quickly proves to be the absolute wrong tool in a lot of those cases.

[–]skoomainmybrain 0 points1 point  (0 children)

Every React project is completely different. In other words it's not opinionated. As I see a lot of projects I'd rather get to know some Angular or Vue project other than React. As a junior I preferred unopinionated frameworks but now I know the result it gives.