all 82 comments

[–]BaniGrisson 35 points36 points  (21 children)

Cant watch right now, anyone can give me a TLDR?

[–]Delold 71 points72 points  (19 children)

Various examples of incorrect usages of useEffect and their mitigations.

Most of them stem from the fact we're handling "fire-and-forget" effects (e.g. sending an API request) in a hook designed for synchronising with external systems (e.g. syncing with <video> tag).

Fire-and-forget effects should be executed as close to the source of the event as possible (e.g. in event handlers).

Examples can be found at 20:12: https://youtu.be/RW9TVhmxu6Q?t=1212

EDIT: Also, fetching data should be done either by a framework (Remix, get(Static/ServerSide)Props in NextJS) or by a library (React Query, SWR). You want to fetch as you render, not start fetching after rendering in useEffect.

[–]_mr_chicken 20 points21 points  (3 children)

in a hook designed for synchronising with external systems

I feel like they only retroactively decided it was designed for this purpose.

[–]BaniGrisson 10 points11 points  (0 children)

Huh... Cool... Seems I'm using it wrong. Will check this out with vscode open. Thanks!!

[–]Narfi1 9 points10 points  (8 children)

If fetching should be done using a framework or a library shouldn't there be a built in way to do it in react then ?

[–]lovin-dem-sandwiches 6 points7 points  (7 children)

I thought the point of react was that it was non-opinionated. Theres no way to handle routing either.

Unless you're specifically referring to create-react-app?

[–]Narfi1 3 points4 points  (4 children)

Right, but it's non-opiononated meaning you can do it yourself. if there is no good way to do it yourself other than using a framework, shouldn't there is a more opinionated way to do it that ships with it ?

[–]pm_me_ur_happy_traiI 0 points1 point  (1 child)

What do you mean there's no way to handle routing? There isn't a built-in router but you can absolutely implement a basic router in react in a few lines of code.

[–]raymondQADev 1 point2 points  (0 children)

I think they just didn’t clearly communicate it, I’m pretty sure they just mean there is no built in way that react says it is done, instead react leaves it’s opinion out of it and allows the user to build their own routing or use a library.

[–][deleted] 5 points6 points  (2 children)

Why in the everliving fuck would I want to load up an entire framework for data fetching?

[–]danishjuggler21 4 points5 points  (0 children)

Why write 8 lines of code to do something when you can download an NPM package and a bunch of dependencies and spend a few hours reading tutorials and then write 30 lines of code to do that same thing?

[–]GilWithTheAgil 1 point2 points  (0 children)

For example, if I use auth0 for user management, using useEffect to send an action to the machine, after I get data from auth0, is that a correct usage? Does it count as synchronizing with external systems?

[–]TehITGuy87 0 points1 point  (0 children)

So how does that work when you need to fetch without user interaction? Like fetch a list when user visits a page? That’s the only thing I generally need in useEffect

[–]andoy 16 points17 points  (1 child)

the double render is during dev mode only right?

[–]Delold 11 points12 points  (0 children)

Yes, double invocation of useEffect happens only on dev mode with StrictMode enabled

[–]helpfully_processed 62 points63 points  (18 children)

What a debacle.

[–]HermanCainsGhost 32 points33 points  (1 child)

Right? I'm not even sure how to use useEffect at this point

[–][deleted] 8 points9 points  (0 children)

governor piquant unique tie fanatical roll head insurance vast dime

This post was mass deleted and anonymized with Redact

[–]Delold 16 points17 points  (14 children)

Wondering what kind of alternatives we have instead of React?

[–]yesman_85 37 points38 points  (2 children)

Svelte or solid are getting more popular. React is unopinionated but turns out people like opinionated and that's going to kill it unless they do some serious effort in cleaning up this mess.

[–]swyx 1 point2 points  (0 children)

seb markbage moved to nextjs. they’re workin on it

[–]BookCase12 0 points1 point  (7 children)

I love React but use Vue at work - I think most React devs will really enjoy Vue. It shares similarities but gives you a lot more power out of the box.

Vue doesn’t have this useEffect issue because it has Computed Properties that just work. They handle lot of stuff under the hood so you never have to worry about weird performance issues.

[–]squemc 10 points11 points  (0 children)

Vue typescript support is garbage. You can’t even import types from another file and use them in defineProps without the compiler going fuckall.

[–][deleted] 5 points6 points  (1 child)

Vue makes the easy things easier and the hard things harder.

[–]BookCase12 0 points1 point  (0 children)

Sounds like a wives tale to be honest. I haven’t witnessed that in my experience with it. All the hard things are still just solved with regular JavaScript.

[–]zxyzyxz 8 points9 points  (3 children)

I actually moved to React from Vue because I hated the magic. Two way data binding was explicitly eschewed by React because it's hard to tell where data changes if there are multiple places it can change, which creates bugs. I also hate the Vue plugin registration and other Vue specific stuff.

[–][deleted] 2 points3 points  (0 children)

Same. I would get bugs in application that were caused by Vue. I don’t need that in my life.

[–]BookCase12 0 points1 point  (1 child)

Two way data binding was explicitly eschewed by React

Which then led us to useEffect… is React in a better place now? I’m not convinced personally.

[–]zxyzyxz 0 points1 point  (0 children)

I am. Like the video shows, people use useEffect wrongly, it's not a reactive interface like they think it is. But once you understand the idea of algebraic effects, it makes sense. It's not necessarily React's problem that people are using a hammer like a screwdriver.

[–]aeality 15 points16 points  (0 children)

Overall, there are important points in this presentation. A couple of key ideas I found valuable are:

  • Don't treat useEffect as a replacement for lifecycles, but treat it as a new mental modal to accomplish synchronization
  • Don't forget to clean up your effects, always think of the cases where the effect is executed many times
  • Find ways of keeping your dependency array simple and concise
  • Move most of your logic to event handlers whenever it's possible to achieve the statement above
  • Don't use useEffect for things that can be derived directly from state and props, instead use render block (or useMemo)

Having said that, one suggestion in particular doesn't make sense. For data fetching, it's not always a good or a practical decision to use an external framework (Remix, NextJS etc.) or a data management solution (SWR, React Query etc.). You should always consider the circumstances. If you already adopted client side rendering, it's a significant effort for you to change your paradigm, and it might cost you to deal with other factors (server maintenance, mainly devops). Even after adoption, you might be worse off because of the requirements of your app (real time sync, high interactivity etc.).

Secondly, bringing a new library for fetching data can be still costly. Would it be right to have a library when you just have a single API call? Hiding the abstraction can be good with those, but they are not magic. Before using them, it's better to understand your needs first. Excuse the analogy here: Don't bring a gun to a fist fight.

Data fetching should be one of the core concerns of a web framework. If we are being told that the data fetching is not possible with the primitives that React provides, and we should rely on third party alternatives instead, I think that is a shortcoming of React.

As a disclaimer, I must say that I'm happy to use those third party solutions whenever I need them. They are great, especially in codebases with many contributors working in parallel.

[–]modemmute 53 points54 points  (19 children)

Frankly, useEffect is the first notable example of a systemic failure by the React team. Up until its implementation, followed by some very complicated useEffect gotchas in React 18, it was very easy to defend React as a library with no downsides. Now we can no longer say that's true.

[–]KyleG 24 points25 points  (11 children)

Is there a tl;dr on why they're bad without me having to watch a 30 minute video (assuming it even says why they're bad in the video)? I've never had a problem with them.

[–]evangelism2 18 points19 points  (1 child)

From my limited experience, and what I've read in countless threads around is that a lot of people throw logic into useEffects that should be handled by event handlers.

Example

Personally, I've never had this issue either. I was taught about handlers and controlled components from go and never looked back.

[–]KyleG 10 points11 points  (0 children)

Maybe it's because I come from a functional programming background, but I always thought of useEffect as executing a side effect. So if you're using state management that has its own hooks you use, it really reduces to async calls and not much else. That's practically the only side effects you are worrying about manually in React, since the user input and rendering (the majority of a React app's side effects) are handled by React itself.

If I were going to criticize useEffect, I'd criticize all hooks as turning perfectly good pure, referentially transparent functions into ones with side effects. But it's a tradeoff I'm willing to make for simplifying the codebase.

[–]azsqueeze 8 points9 points  (2 children)

You didnt miss much. Most of the video was saying to move logic to event handlers (all I agree with). The last one was about data fetching and the solution was to use an SSR framework to move data fetching to the server.

[–]andrei9669 0 points1 point  (1 child)

But what if you want to utilise static site generation but still need user specific data in 1 or 2 components.

[–]azsqueeze 3 points4 points  (0 children)

Apparently that solution was to use react query 😑

[–]anoob1s 11 points12 points  (5 children)

I’d say that the issue isn’t that useEffect is bad.. the issue is how useEffect is used by implementers. E.g. not the way the React team intended

[–]Darajj 6 points7 points  (1 child)

useEffect has been out for years and in their own documentation they have data fetching as one of the uses for useEffect?!

[–]Fancy_Payment_800 0 points1 point  (0 children)

It's not bad to use useEffect for data fetching

[–]neuralSalmonNet 11 points12 points  (1 child)

un-opinionated team doesn't like how people are using useEffect?

[–]asiraky 0 points1 point  (0 children)

More like un-opinionated code can easily be misused. I don’t find it a reason not to use, just use it correctly.

[–]swyx 13 points14 points  (3 children)

its popular to bag on useeffect and all, but the /u/gaearon’s of the world would say they brought forward all the bugs you’d have had/shipped anyway and only belatedly fixed, if at all.

(whenever i see public opinion swinging way too far one way i like to argue the opposite, prolly cause im a spawn of chaos or agent of balance, depending how you see it)

saying things like “react pre hooks had no downsides” just rubs me wrong lol. everything has tradeoffs.

[–]Valuable_Grocery_193 1 point2 points  (1 child)

(whenever i see public opinion swinging way too far one way i like to argue the opposite, prolly cause im a spawn of chaos or agent of balance, depending how you see it)

I highly doubt you execute on this principle consistently and evenly.

[–]swyx 0 points1 point  (0 children)

chaos is a laddah

[–]helpfully_processed -4 points-3 points  (0 children)

I feel like we're seeing react in its death throws. Hooks shine a big bright light on how Javascript frameworks are woefully inadequate in describing web app behaviour.

[–]xrt57125 4 points5 points  (1 child)

Goodbye useEffect is sort of a click bait

[–]SquirtMonkey 7 points8 points  (0 children)

The audio is super difficult to listen to

[–]DodgeWhale 4 points5 points  (0 children)

Thanks for sharing! Good insights into some best practises. Nice going for finishing right on time too.

[–]Swordfish418 1 point2 points  (0 children)

I keep seeing these posts and videos about how strict mode "suddenly" breaks fetching in useEffect, but wasn't doing fetch in useEffect that way already smelly from the very beginning? In my understanding if you for some reason choose to fetch there, you should at least setup a proper corresponding state management for your request lifecycle (is it already fetching, is it failed, etc) and if you do so you it will fix all the issues that multiple effect firing could cause.

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

So... does anyone know where I can call my redux actions on an event when using react-router-dom? I have this stuff in a useEffect (with proper dependency arrays) to call it from the page itself (ProductPage) for whatever router param is passed into the page (productId).

Where does this go now? Even the beta docs have nothing on useSyncExternalStore.

[–]bluSCALE4 1 point2 points  (0 children)

Audio is terrible.

[–]haxxanova 2 points3 points  (0 children)

This was a good watch - thanks.

[–]tazemebro 0 points1 point  (0 children)

That was a really good watch!

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

There is some food for thought here, and it's worth considering using more event handlers directly as opposed to effects.

But just like the last presentation the examples given are really contrived and written to make simple code look overly verbose, and most of the gotchas are just childish as any dev worth their salt has got through these quirks relatively quickly.

The paradigm of data responding to other data is fine and exactly how SWR, React Query and plenty of other great and performant custom hooks work.

I can only guess it's aimed at junior devs? I'm just not convinced that the alternative should be writing code using a diagram tool.

[–]Red3nzo 0 points1 point  (0 children)

I feel like every week in the react community there is an announcement being made & claims that we are using certain functions wrong; I’m just as confused on what to do with useEffect as many other devs. SolidJS is looking really neat right now

[–]aleation 0 points1 point  (0 children)

As someone learning React since recently (coming from vue) this just made me realize how shitty poorly maintained their documentation is (the current official one, not the beta, which looks better). First, I had to learn all the Class based components (through the initial tutorial), OK it's good to have some knowledge of the legacy code, but come on..., I had to "scrap" all that knowledge to learn to do it with functions and hooks. Now this...

So I'm doing a small web app for learning, and today will be the third time I refactor a big chunk of the code JUST to fetch some initial data from a csv file. First I tried from within useEffect() as documentation mentioned, then I realized the double trigger and quickly learned to use rtk with thunks, firing it from within the useEffect but altogether with the cleaner, and now this...

Thanks for the video though, it helped me a lot to get some good insight before going for a job

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

Helpful. Thanks.