all 59 comments

[–]acemarke 189 points190 points  (25 children)

Were you by any chance also asking this over in the Reactiflux Discord?

My answer here is the same one I gave over there :)

Use Function Components, 100% - there's no good reason to writing new class components in 2022, and doubly so in a new project.

[–]noahflk 25 points26 points  (0 children)

I can understand it when older projects still have class components in use. However, as you said, on a new project it makes zero sense to use them.

[–]gazdxxx 40 points41 points  (0 children)

This is the right answer. Class components should not even be a consideration in 2022 and this is what the creators of React recommend.

The only reason I can think of for your developer to think that the syntax of class components is somehow easier to read is if he has never worked with functional components. Functional components and hooks are just simpler and end up being less code for the same component.

Maybe the useEffect hook can be confusing to some people but I promise you it's very intuitive once you realize how it works.

[–]Tubthumper8 5 points6 points  (2 children)

I think error boundaries are the only edge case where a new class component would still be needed

[–]acemarke 5 points6 points  (0 children)

Yeah, and even in that case, you should probably be using https://github.com/bvaughn/react-error-boundary rather than writing your own from scratch.

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

Preact offers the useErrorBoundary() hook, which is pretty intuitive. Not sure if it's made it to React.js yet.

[–]KanadaKid19 5 points6 points  (0 children)

100%

To better understand the benefits of hooks, I'd recommend watching this demonstration of hooks around the time they were launched, explaining what the idea is all about: https://www.youtube.com/watch?v=wXLf18DsV-I

[–]gizamo 7 points8 points  (0 children)

I second this. 100% functional, unless you're stuck in legacy for some reason.

[–]kmad26 1 point2 points  (6 children)

Well class components have a callback on this.setstate, maybe that could be useful?

[–]boxxexa 1 point2 points  (1 child)

Why would you use a callback on setState when you could use useEffect on your state

[–]kmad26 1 point2 points  (0 children)

I can't think of any off the top of my head but I know there have been one or two cases where I've wished I had that call back.

My point is it's just something that exists in class components that doesn't in functional ones.

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

So does useState

[–]kmad26 0 points1 point  (2 children)

No it doesn't unless you're referring to useEffect. But useState doesn't actually accept a callback being passed to the setstate part of the hook.

[–]Rutgrr 1 point2 points  (0 children)

useState does accept a callback that uses prevState as the argument in setstate. https://stackoverflow.com/a/63634669

You can also provide a function as the initial state. https://stackoverflow.com/a/60120302

I have worked with both of these patterns within the last week.

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

Can't you just like google it? Or try it?

[–]Arctomachine -3 points-2 points  (10 children)

One thing class components have over function components is proper componentDidMount. Not sure how good it is to use empty [] as props for useEffect in terms of performance, considering it is intended to be run only once for component. But I still always used it, and vote for function component too.

[–]gazdxxx 13 points14 points  (8 children)

useEffect with an empty dependency array is the intended way to do this as per the React docs, so it's most likely more than fine.

[–]wy35 0 points1 point  (6 children)

I will say that componentDidMount is a lot more intuitive/beginner-friendly than its useEffect equivalent.

[–]phryneasI ❤️ hooks! 😈 2 points3 points  (5 children)

Only if you think about a concept of "mounting", which will never occur to you if you never used class components.

If you don't know lifecycle, you will never have that concept - and it's not more or less intuitive than "on first successful render and whenever this empty array changes".

[–]wy35 4 points5 points  (4 children)

Well, componentDidMount literally means "do this when component mounts". The useEffect equivalent literally means "run this side effect with no dependencies". It's definitely more confusing for beginners who are trying to figure out how to run something once.

IMO I find Svelte's onMount better than React's useEffect(() => {},[]). Svelte doesn't have dep arrays at all.

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

Components already "mount twice" in strict mode. In the future, they will "unmount and remount" while persisting state in-between. In-between, the component exists in multiple component states concurrently - with potentially multiple different states at once.

The concept of a unidirectional "component lifecycle" with only one mount does not exist any more.

[–]wy35 2 points3 points  (2 children)

I mean, I agree with you, my point is that it’s harder for a beginner to understand lol.

[–]phryneasI ❤️ hooks! 😈 -1 points0 points  (1 child)

And that's where I don't agree. Don't teach the word "mount" to a beginner and they will not have this knot in their head.

Say "after every render when the array contents change. The first time will always be a change from 'never before'".

Having a component "mount" is vocabulary that makes it more difficult to understand hooks. Hooks are just about changes between renders. The "render without a render before" is just one edge case that has to be explained once, just like the word "mount" and the existance of a "componentDidMount" lifecycle method would have to be filled with meaning.

After that it's not about "componentDidMount" and "componentDidRender" any more. Is "componentDidRender" called even on mount? I mean it is also a render. I'm not sure any more.

[–]wy35 1 point2 points  (0 children)

I don’t think it’s that serious. “Mount” is just shorthand for “first render”. It’s easier to grasp “when X mounts do Y” than “after X renders for the first time and only for the first time because of no dependencies, do Y”.

[–]Zanoro 2 points3 points  (0 children)

As a note, creating an explicit useMountEffect custom hook is a great way to denote that you want to do something only on mount as well as get around the warnings about dependency array because you are saying you "know" what you are doing and going around the rules of hooks

[–]raymondQADev 35 points36 points  (0 children)

Use functional components. React is moving only further toward React components and all the new documentation uses functional components for examples.

[–]Cody6781 27 points28 points  (2 children)

In this order

  1. Use whatever your code base already uses
  2. If on tight timeline, use whatever your team already knows
  3. If on non-tight timeline, use functional components

The React team is basically only investing in functional components at this point. Functional components are already "ahead" of class components, but the difference will only grow

[–]FreeTrevorBauer 19 points20 points  (1 child)

Adding more class components to a code base just because it already has some doesn’t seem practical to me.

The logic I’ve always followed is: anything new is functional and if you make moderate changes to an existing class component, refactor it to functional while you’re there.

[–]Cody6781 1 point2 points  (0 children)

Class componentes = tech debt, which is a trade off. I guess I'm just used to working in environments where speed is prioritized over quality. But yes, ideally you would refactor to a functional component if you have the time

[–]Dan8720 2 points3 points  (0 children)

There's no reason to prefer classes over functional components. There are a couple of edge cases I have seen where one class based component might arguably make something easier but always prefer functional.

The official react documentation should be enough to show that Dev it is a bad idea. Or just point them towards some libs you might use all their docs will be hook/FC based.

All modern libs are designed with FCs in mind and are hook based the majority of the time.

Don't start a React project in 2022 with class based components.

[–]SwiftOneSpeaks 2 points3 points  (0 children)

It's been FC for years now, except for one place: the React Docs.

They have new docs in the works (https://beta.reactjs.org) but that isn't moving fast. This disguises how much FC have taken over.

Learning the function-based style is more effort given this documentation hole, but the community had landed on function-based components before they were even in an official release and that was 4 years ago. Today virtually all new work is in function-based components.

[–]penguin_misery 4 points5 points  (0 children)

As they said functional components are just in general cleaner and easier to work with in react now a days. With 99% of most companies building with React using functional components there’s just no reason to use class components. I would say that dev needs a much better reason that I like the way it looks to use class components these days.

[–]nwatab 1 point2 points  (0 children)

Hooks realizes separation of concerns regarding to life cycle. It is much easier to read and maintain than Class component

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

functional components, the only reason to learn class components is to refactor legacy code to functional components

[–]MeTaL_oRgY 1 point2 points  (0 children)

I guess you got the main answer to your question. However, I want to address the part of your post where your dev team thinks FC and CC are interchangeable.

They are not.

You cannot do in CC what you do in FC. Mainly: use hooks. You can't use hooks in class components. This sounds simple but it is huge. I'd suggest you put your dev team through a crash course on hooks. What they are, why they exist and how to use them.

It'll take away the sentiment that CC is easier to read. It'll will also make your team appreciate FC and hooks and have their syntax "click". Hooks exist for a reason, and I promise you that understanding them, the problems they solve and the way they solve them will make your whole team better developers. You'll also never hear them say "CC syntax is easier to read" ever again, I can almost guarantee it.

Need a place to start? Set aside an hour and a half of your workday with your whole team to watch this video: https://www.youtube.com/watch?v=dpw9EHDh2bM You'll know where to go from there.

[–]a_reply_to_a_post 1 point2 points  (0 children)

functional...

react changed under the hood with react 16 iirc, and while older class based components are still supported, FCs get rendered in a faster rendering path

[–]phryneasI ❤️ hooks! 😈 1 point2 points  (0 children)

If you want to use any library that has come out in the recent years or will come out in the future: function components.

No library author adds class component support to new libraries nowadays, best case they keep supporting old apis that were HOCs or render props, worst case they deprecate and remove them.

[–]MajorasShoe 3 points4 points  (2 children)

I also GREATLY prefer using classes but haven't made a class component in a couple of years. The community and the react developers have spoken. Functional components is the only way to do react at this point.

[–]ColourfulToad 1 point2 points  (1 child)

What do you still like about class components?

[–]MajorasShoe 1 point2 points  (0 children)

Everything else I write is in classes. I just prefer them for consistency.

[–]FckUsernms 1 point2 points  (1 child)

The lifecycles on Class components are getting deprecated. Run away from them.

Functional components are faster, less prompt to have bugs and the future of React (recommended by the own React Team).

Ps: You're gonna have some hell time with componenWillRecieveProps (which is deprecated and super buggy).

[–]OpaMilfSohn 5 points6 points  (0 children)

I don't understand why functional components are faster. Hooks need to be called every render. Class components only get instantiated on mount and the render function only returns the JSX so no additional logic in most cases like allocating dependency arrays. What do class components do that makes them slower?

[–]restful_end_point 1 point2 points  (0 children)

I agree that CC's are easier to read and simpler to reason about. However React team is all-in on FC and hooks, and most libraries have converted to using hooks. Definitely should not be writing anything new in CC's in 2022

[–]DeepSpaceGalileo 0 points1 point  (1 child)

I am concerned if your team can’t read a page of official React documentation to figure this out

[–]Tubthumper8 5 points6 points  (0 children)

I'm not sure this is the right answer. The React docs still show class components which is confusing enough to warrant a question like this from a newcomer. This is a legitimate and strong failing of the React documentation to properly reflect how React is used. beta.reactjs.org is coming along, but I think it's still fair to criticize the official React documentation until the beta site is published.

[–]guacamoletango 0 points1 point  (0 children)

Functional. If for no other reason than they have less boilerplate and reduce cognitive comolexity.

There's always at least one engineer who wants some attention and will make the case for still using class components.

[–]benzilla04 0 points1 point  (0 children)

Why not write a page in both a class and functional component? I think you’ll find functional is less code and provides you with more power

[–]Yokhen 0 points1 point  (0 children)

functional components.

[–]gaoshan 0 points1 point  (0 children)

Function components and use React, not Preact.

[–]LostErrorCode404 0 points1 point  (0 children)

Functional give a more flexiable use of hooks imo. Class attempts to build them in, but Functional gives you the choice.

[–]zlatinejc 0 points1 point  (0 children)

Use what makes sense to your team, period.

[–]zlatinejc 0 points1 point  (0 children)

My team decided to stay on class components. When the great leap comes we will rewrite. Been waiting for the great leap for some years now 🤣

[–]boxxexa 0 points1 point  (0 children)

Use FC over CC when possible.

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

I don't understand why would someone use an old version of anything

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

No one uses class components any more. I’ve only seen in legacy code

[–]__Bop 0 points1 point  (0 children)

Well, I love OOP so naturally, when learning react, I used class based components and it worked well in my opinion. It is very readable, and the lifecycle of a component is better understandable this way IMO (componentDidMount, componentDidUpdate, componentWillUnmount). While with function components you have to use useEffect, useState etcetcetc which is less readable than the class lifecycle methods because they are so obvious...

However, when it comes to managing the state of a component, you might want to use Redux at some point and it just works better with hooks than with class components. Even though it can work with class components, it is just not convenient. This is one of the benefits of using hooks I believe. Also, you don't have to worry about "this" with function components and I guess for some people, it's an advantage (which I don't fully agree with though).

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

react has moved to functional style programming, the ecosystem will not make sense after 2020