5 ms·
A lot of the confusion people have with useEffect is the React team’s dishonest approach to it. useEffect WAS for side-effects. That’s why it’s named that. Th
by rhaway84773 4y ago
A lot of the confusion people have with useEffect is the React team’s dishonest approach to it.
useEffect WAS for side-effects. That’s why it’s named that.
That’s literally the first sentence in the Effects hook page in the current non-Beta documentation.
> The Effect Hook lets you perform side effects in function components:
https://reactjs.org/docs/hooks-effect.html https://reactjs.org/docs/hooks-effect.html
I completely agree that useEffect should not be used for side effects. The concept of using it to sync with an external system makes far more sense.
But this is a very different and new understanding of what useEffect is. The React team, for whatever reason, does not present it as that. They do not point out that, yes, this was originally supposed to be for effects but they realized that this was a bad idea and have refined how they believe it should be used.
Instead, the documentation and commentary around such changes never point out they are changes and just present them as how things are. Which leads to a tremendous amount of confusion among new developers learning React, because it’s never clear what the actual correct approach is, since you rarely come across commentary in a temporally ordered way.
If the Beta docs included the statement “we used to recommend this for side effects, but now don’t”, any newbie reading that will forever understand why the highly upvoted SO answer from 3 years ago recommends using useEffect for a certain side effect but today, that is probably not the right solution.
- johnfn 4y agoHuh? Syncing with an external system IS a side effect; there's no inconsistency in messaging. React considers everything not part of React to be an external system (document, external store, backend...)
- onion2k 4y agoThe concept of using it to sync with an external system makes far more sense. React 18 introduced a new hook called useSyncExternalStore for that, which implies useEffect isn't quite right for that purpose otherwise there'd be no need for a new hook.
- belmont_sup 4y agoFirst time I saw this hook. This seems more like a library implementor’s hook to sync stores from redux, mobx, etc. You can of course wrap your GET/POST requests to an external network API too but that seems like a lot of unnecessary code to pull in external data.
- onion2k 4y agoYou never just want to "pull in external data" in a real app though. You need to make the request, deal with injecting auth tokens or headers, handle errors, handle different responses, update global and local state, possibly trigger side effects when the loading starts and ends, do something in a "finally" callback... If your app is non-trivial then you'll almost always end up using a library of some sort. That's where useSyncExternalStore is useful. If you're using useEffect then you're probably not making external requests well. If you don't need it then you should be questioning whether you even need React, not whether or not you need useEffect.
- belmont_sup 4y agoI do agree that better built-in methods should exist that does most of what people have been using useEffect for. Many frameworks come with many tools for specific use cases but react has always left it to the community. If this or new ones are helpful enough, then I’m up to use them. However, your last statement is a bit too presumptuous to assume that not needing useSyncExternalStore means that someone does not need React. I recommend Remix for most apps now if possible, and the number of times anyone needs to use either hooks discussed is very minimal. Remix uses React. Think your last reply overlaps with the first half of my message. I reach for swr or similar to manage the lifecycle of client side network requests (or any async requests) if necessary. I would imagine that these libraries or new ones adopt useSyncExternalStore internally. If I want to use this hook myself, it seems quite a bit more work to have to write a subscription-based store just to make certain network requests. Many apps aren’t real time either. Take a single case: analytics. I want it to trigger whenever the page loads (and can’t be done server side for whatever reason). Are you saying that I need the kitchen sink to make this fire-and-forget request? useEffect is fine here. Am I not making an external request well? I just read the useSyncExternalStore RFC. Its primary purpose is to handle external state change in a concurrent environment. Makes sense. Is it to become the default for all “external requests?” Idk. But let’s agree that not all requests require the same care.
- treis 4y ago>The concept of using it to sync with an external system makes far more sense. Why not do that in your setState function?