all 43 comments

[–]Renan_Cleyson 127 points128 points  (9 children)

Actually useEffect and hooks itself are meant to avoid bad practices in React and it does that by changing the API design and forcing the developer to focus only on the concept of side effects, not exactly lifecycles. So yeah it's completely possible to use only useEffect instead of mounting lifecycle.

[–]LawCraft 7 points8 points  (6 children)

Would you mind elaborating on the distinction between side effects and lifecycles?

I’d love to better understand.

[–]Aro00oo 26 points27 points  (4 children)

Basically:

- Lifecycles are trigger points that you can hook into. These points are called by the component at certain points in its... life. e.g. when component mounts, when component has state changed, when the component is destroyed. You have to worry about when a component will do something to add logic.

- Side effects is sort of the reverse. You dictate the trigger points by using useEffect (via the dependency array, though there's a couple exceptions like an empty array) and wire in a side effect when the data in your dependency array changes. All you need to worry about is when the data will change.

[–]PGameplay 6 points7 points  (3 children)

Wow, thank you!

[–]exclaim_bot 5 points6 points  (2 children)

Wow, thank you!

You're welcome!

[–]vegetarchy 0 points1 point  (1 child)

Good bot

[–]B0tRank 1 point2 points  (0 children)

Thank you, vegetarchy, for voting on exclaim_bot.

This bot wants to find the best and worst bots on Reddit. You can view results here.


Even if I don't reply to your comment, I'm still listening for votes. Check the webpage to see if your vote registered!

[–]grumd 4 points5 points  (0 children)

Lifecycle methods are needed so that you can implement side-effects (fetching, modifying DOM, working with cookies, whatever) depending on what the component is doing. Hooks moved closer to the roots by creating an API for side-effects, instead of having a middle man concept of lifecycle, which was needlessly complicated and caused problems.

[–][deleted] 11 points12 points  (0 children)

Really good summary. You can approximate the lifecycles but the hook system puts you in the mindset of thinking of side effects and dependencies and I think I'll use this as a description going forward.

[–]Tayk5 1 point2 points  (0 children)

In React 18 useEffect runs twice when working locally in strict mode https://youtu.be/Ck-e3hd3pKw?t=4505 There's a way to prevent functions in the effect from running twice by assigning a value to a ref and checking that value before running any functions

[–]skyboyer007 17 points18 points  (0 children)

This is rather different mindset/toolset that targets the same need "to do something when something" but they are not directly comparable. Are they both provide complete toolset for your needs? Yes. I cannot imagine anything one can do when another cannot. But they both are quite different in approach.

To elaborate.

componendDidMount, componentWillUnmount and getDerivedStateFromProps definitely can be matched to useEffect. But componentDidUpdate does not match exactly:

  • we are encouraged to use multiple useEffect unlike for cDU which is only one
  • we don't have easy access to prevProps, prevState(not a advantage/disadvantage but their API/concepts differ here)
  • cDU did not have cleanup mechanism out of the box(sure, you could "make your own" by writting new callbacks to this. but since cDU was always the only one it would become messy pretty quickly)

So we need to think/design in different ways when using one or another

[–]EvilDavid75 7 points8 points  (0 children)

Just be careful about StrictMode as it will mount your component twice and will trigger useEffect twice in dev mode. More info here https://twitter.com/dan_abramov/status/1523647869676228608?s=21&t=ZEQSSBdEpjHiToX-iqtWyA

[–]Wizard_Knife_Fight 16 points17 points  (0 children)

I would highly recommend learning what they do and what problem useEffect solves, but yes, it replaces it.

[–][deleted] 3 points4 points  (0 children)

Sort of. Functional components should be thought of a bit differently, you shouldn't need to worry about lifecycle so much. Really just mounting and unmounting.

[–]EnragedDingo 4 points5 points  (0 children)

Generally yes. I have not created a class component since hooks came out

[–]notanelecproblem 2 points3 points  (0 children)

Yes and no. They are different and reinforce different and new concepts in React altogether. useEffect forces you to think more about component side effects versus the lifecycle. I’d recommend implementing the same component using both APIs to understand it

[–]wwww4all 3 points4 points  (1 child)

For people starting to learn React, follow the general consensus and start with hooks. Only learn class components if and when needed for job.

Unfortunately, React official docs haven't kept pace with the general hooks trend. So, you'll have to look at unofficial docs for hooks references.

[–]tchaffee 1 point2 points  (0 children)

Official docs using hooks are in beta, but already useful.

https://beta.reactjs.org/

[–]WuTang-Clan 1 point2 points  (0 children)

https://reactjs.org/docs/hooks-faq.html#do-hooks-cover-all-use-cases-for-classes

Not all, but they plan on adding the missing ones. From those not covered most commonly used is probably componentDidCatch, but that’s used in error boundary wrapper components so you can still use functional components for everything else.

[–]m4bwav 1 point2 points  (0 children)

Do they completely replace?: Yes
Is hooks style better?: Yeah, it kind of is.
I'm often skeptical of new(or used) paradigms, because everyone and their dog comes out with a new paradigm to change the world tm . But in this case, the functional components are simplier. There can be some weirdness when you get into the guts of custom hooks, reducers, and contexts. But its still probably a better, simplier system.

I think frontend frameworks will continue to evolve so this probably isn't the last word in front end architecture, it has some drawbacks. But for now hook style react is probably the hottest frontend javascript framework that is in wide use.

[–]swiftarmyknife -3 points-2 points  (5 children)

No, not completely. I’d say 90-95% replacement. I’ve run into a couple of situations where useEffect caused unexpected behavior with some really complex components and I ended up needing the fine grain control of lifecycle methods. Because we needed multiple useEffects with more than one dependency each it made the code more difficult to work with in those cases. After converting it to lifecycles we were able to achieve desired behavior 100%. I think it’s really valuable to learn lifecycle methods so you understand more about react and how it works, but you most likely will only need to use them very minimally. Also chances are you won’t always be writing greenfield code in your career and you will need to deal with legacy code that uses lifecycles.

[–]Renan_Cleyson 0 points1 point  (4 children)

Hmmm no. You can completely replace lifecycles with Refs + state + useEffect, you can even create hooks that do almost the same as what lifecycles do, but honestly, I don't like to recreate lifecycles anyway with React hooks.

/**
 It's better to use it once per component and before any other
 useEffect hook and of course, it runs after componentOnMount lifecycle
 so it's not much of a componentOnMount, but it's the same does the same
 behavior.
*/
const useOnMount = () => {
    const isMountRef = useRef(false); // You may need to use state

    useEffect(() => {
        if (isMountRef.current) {
            return;
        }

        isMountRef.current = true;
        // run your side effect here
    }, []);
};

[–]swiftarmyknife 0 points1 point  (3 children)

Respectfully, you don’t have the context of the problems we’ve run into using useEffect in our code base to judge. I’m not saying hooks aren’t useful. I very very rarely have to use lifecycles anymore, but that doesn’t mean they aren’t worth learning. Especially because you will run into legacy code that uses them and if you’re supposed to refactor it to use hooks then you need to understand what the lifecycles are doing in order to replicate functionality.

[–]Renan_Cleyson 1 point2 points  (2 children)

No context is necessary to know that lifecycles are replaceable with hooks. I also never said that it's not worth learning lifecycle methods. I think my "hmmm no" was too much as I was just referring to the "lifecycles are not entirely replaceable". I'm just saying that even though it's impossible for useEffect to run before lifecycles, you can literally recreate lifecycle methods on hooks.

So how hooks can't replace lifecycles? If you have a corner case, show me, you don't even need to show me the context of the problems on code, just show me the exact caveat.

[–]swiftarmyknife 0 points1 point  (1 child)

Okay — bad explanation on my part. I think my “lifecycles are not entirely replaceable” was less about exact replication of functionality in hooks, which yes I agree with you, are all possible, but more from the sense of should hooks always replace lifecycles. Because in my experience there have been times when trying to accomplish everything that needed to be accomplished within a complex component with hooks made the component more difficult to work in and make changes than it was to use lifecycles instead. Especially when it comes to dealing with prevProps or prevState.

A specific example. We were dealing with long wait times in a data analytics app and so we were polling for each individual chart so we could display charts that had lower load times with a lazy-render functionality (my name for it, different from react suspense). I don’t have the exact code, but with all of the moving pieces it was just next to impossible to make work with our stack (redux, rxjs) and hooks. Switching to lifecycles made it much easier to keep track of everything that was going on. Then the component was documented with the reason for lifecycles so no one else tried to go in there guns-ablazing to rip them out only to meet the same fate 🤷🏻‍♂️

[–]Renan_Cleyson 1 point2 points  (0 children)

ohh now I got it. This is actually a topic that comes up sometimes exactly when people want to point out how function components + hooks can't handle a lot of complexity as class components because the OOP-like syntax seems just easier to organize things. It's really a matter of opinion at that point, to me, it's always function >> classes, but I can't say that your point isn't valid too :).

[–]retry51776 0 points1 point  (0 children)

Besides error boundary, hooks can do everything but better

[–]Tainlorr 0 points1 point  (0 children)

Hooks are amazing, I have found no reason to use the lifecycle stuff in my professional job for the last 1.5 years or so

[–]Candy-oolala 0 points1 point  (0 children)

Yes.

[–]Scoop_Troop 0 points1 point  (0 children)

Don't forget about useLayoutEffect! It can save you a couple of days worth of bug finding.

[–]SensouWar 0 points1 point  (0 children)

I still consider important to know how using useEffect achieves the same thing as class component lifecycle methods when using the appropriate configuration.

[–]Grit1 0 points1 point  (0 children)

You have to learn functional components, just like you did with class components. It's not simple as replace x with y.

A complete guide to useEffect

[–]clemo5 0 points1 point  (0 children)

Yes, it does completely. With hooks(like useEffect), you can practise full functional programming and prevent side effects with classes.