Now, before I get cancelled, let me explain đ I'm on the cusp of the boundary between Gen Y and Gen Z and I learnt React during the class component era. However, my stint with class components was only 2 years, which coincidentally is also the number of years between myself and the official cutoff of Gen Y. This made me think that - most of Gen Z would likely have learnt React from a point of functional components & hooks!
Consider this letter my reflections on the generational divide between the "Class Component Generation" and the "New Gen of React Devs," along with unsolicited coding tips for bridging that gap. And so really, the inclusive title is:
âA Love Letter to the New Gen of React Devs from the Class Component Gen of React Devsâ
My Dearest Gen Z / New Gen of React devs,
Whether from the bustling virtual classrooms of coding bootcamps to turning caffeine into code during late night coding sessions, we've both embarked upon our own unique journeys to learning React.
Yourâs began with functional components, where as for us, it was with class components.
When hooks stole our heartâs
In 2019, with the release of Hooks in React 16.8, the way we all learned React changed significantly. Prior to hooks, functional components were largely used for simple, stateless rendering, while class components handled the more complex logic, state management, and lifecycle methods. However, with the introduction of hooks, functional components gained the ability to manage state and side effects and it altered the way React applications were built.
Justifiably, the hooks docs assumed the reader was familiar with class components. However, those learning React post-2018 likely didn't prioritise learning class components, as the React ecosystem was shifting towards a functional component approach, leaving little incentive to learn the "old way." This caused some:
Unintended Differences (but, Differences make the heart grow fonder)
As a result of your learning journey, there are some notable "generational differences", highlighted in the quotes below, in your approach to React development compared to ours. Let us explain each difference and how it came to be:
1. âYour generation didnât learn the life cycle methodsâ
Explanation: This is the most significant difference. For us, the class components generation, managing state meant we were forced to understand the nuances of the lifecycle methods (componentDidMount()
, componentDidUpdate()
, and componentWillUnmount()
). These methods provided clear entry points for initialising, updating, and cleaning up state, that hooks abstracted away.
2. âYour generation tend to jump to state management librariesâ
Explanation: Prior to hooks, integrating Redux into a React application was a PAIN. It required a good understanding of the flux architecture and oh-so-much boilerplate code. So even though, with hooks, the process of integrating Redux (or rather Redux Toolkit) has become much easier, the scars of past serve as a reminder of the potential complexities making us less likely to reach for a state management library.
3. âYour generation doesnât like using TypeScriptâ
Explanation: Class components provided an object-oriented programming (OOP) approach to React, which aligns well with the typed nature of TypeScript. Consequently, we are more inclined to TypeScript as a means of enforcing code maintainability and improving the type safety that was lost when we switched to functional components.
4. âYour generation love using hooksâ
Explanation: Class components had specific lifecycle methods like shouldComponentUpdate
that allowed for manual control over component re-rendering, encouraging developers to think about performance optimisation. With hooks like useCallback
and useMemo
, the optimisation techniques are not as explicit or intuitive, making it harder to identify the most effective use of these hooks. Similarly, because class components required a deeper understanding of the component lifecycle and how it relates to rendering and updating we were able to understand when to touch the DOM when using useRef()
.
5. âYour generation take testing for grantedâ
Explanation: (this one is probably my most opinionated) The step-by-step nature of class components encouraged testing practices, as we had to address each component's lifecycle events and behaviours individually. Additionally, class components required more explicit setup for testing, such as mocking lifecycle methods. Comparatively, testing functional components is much âeasierâ now, so for us its a âno brainerâ, while for you it may seem like an afterthought.
So I guess what iâm trying to say is, we may have been too quick to judge your coding choices and a little too harsh in our code reviews. But upon reflection, it's clear that our different learning journeys have shaped our approach to React development. And just as we wouldn't expect you to understand our love for flip phones and skinny jeans, it's unfair to expect you to have the same understanding of class components and lifecycle methods.
So now, instead of dwelling on our differences, let's focus on how we can bridge the gap and learn from each other.
Instead of criticism, allow us to offer: React Love Advice
Dont carry unneccessary baggage: Avoid storing unneeded state (âYour generation didnât learn the life cycle methodsâ)
- We learned the hard way, that unnecessary state can quickly lead to complexity and performance issues. Avoid storing state that can be calculated from other state values, prop values, or isn't essential.
- Enforce Immutability, don't transform data in state â transform that data while rendering instead
- Watch out for duplicated or deeply nested state.
Master the love language of hooks! (âYour generation love using hooksâ)
- Managing the component lifecycle explicitly taught us the importance of separating concern.
useEffect
may seem like a simple way to handle side effects and state updates, however weâve learned that multiple useEffect calls with many dependencies can quickly lead to spaghetti code and performance issues. - On the flip side, watch out for missing dependencies in useEffects as this can lead to unexpected behaviour in your application.
- Make use of the cleanup function returned by useEffect to avoid memory leaks and properly handle component unmounts.
- Don't overuse hooks like
useMemo
anduseCallback
, as premature optimisation, as this can have the opposite effect to its intended purpose due the the overhead of these hooks - Theres a great talk on using hooks: using useEffect Effectively by David Khourshid or 12 useState & useEffect Mistakes Junior React Developers Still Make in 2024. by ByteGrad
TypeScripting our way to a stronger relationship! (âYour generation donât like using TypeScriptâ)
- TypeScript improves type safety, maintainability, and scalability â all crucial as your applications grow!
- Many popular libraries and frameworks (e.g. React Native) are now going down the TypeScript as a default route.
Managing Our Love State (Management) (âYour generation jump to state management librariesâ)
- Understand when to use a State Management Library, only reach for Redux or similar libraries when you have a clear use case.
- At the same time donât stick everything into one Context, break down your state into smaller, more manageable contexts that are specific to different parts of your application. This is a great article from Kent C Dodds.
- For managing asynchronous operations, consider a library like TanStack Query.
Nurturing Our Love with Tests (âYour generation take testing for grantedâ)
- Keep components focused on a single responsibility. Refactor complex logic into custom hooks or utility functions. A good reference is the book Clean Code by Robert Martin.
- Make sure your component isnât too large, coupled or nested and think about the dependency flow.
- Follow principles like unidirectional data flow, atomic design, and decoupling components.
- Favour composability over inheritance. I really like this page from the legacy react docs.
- Post hooks, the project structure of React changed (e.g. no more container). Consider folders for hooks, context, and types and ensure you are thinking about the core principles of readability, maintainability, and reusability from the star. This will save you refactoring headaches down the road.
- Pass dependencies into a function or component from the outside, rather than having the function or component create or manage its dependencies internally (Dependency Injection).
In the future, we will get through this together
So now as we venture into the unknown world of React 19 with its Server Components and the new React Compiler. We can share notes and ponder together on whether the compiler will ease the pains of useMemo(), useCallback() or if we are going to have to work together to write an article for the post-compiler generation đ
With all my love,
Gen Y / The Class Component Generation of React Developers
Massive thank-you to Joe Brady, Charlotte Isambart, Justin Zelinsky, Justin Kek, @hellonehha and Antony Clements who fed into the Lessons Learnt
Please drop any comments of other lessons learnt / your experience!
Top comments (33)
Great read (even as a Gen X'er).
I feel software development is going backwards but I guess that is more to do with the platform (web) whereas I coded for Win32/Win64.
I did years of OO and component re-use and encapsulation was a thing and as you mention React started this way before going, dare I say, quick and dirty.
But web dev isn't quick and dirty, its slow and painful having to have UI/API Layer/DB and having to marshall data back and forth between the 3 tiers. I (30 years ago with Delphi) I could do OO, visual inheritance, 2-tier, 3-tier, WYSIWYG development so could churn out apps way way faster than now.
Hey! Thank-you. I know what you mean, React has a very interesting paradigm where some new developers may not have ever touched OOP! Really interesting to hear your perspective, thank-you for sharing!
This was a fun return to the past, and a nice look forward!
Thank-you Jamon! Since you're one of the major players in the RN community, is there any similar trends specific to RN you have seen?
I think the new architecture and autolinking and before Expo was viable -- might make a good talk at Chain React actually.
Ooo what a great idea! Theres probably so many things I "take for granted" in RN, would definitely be very interested!
CFP is still open! ChainReactConf.com
This was a great read!
I am in the "i learned class components" group too. I wonder what the younger developers think about these differences.
I especially see the value of your opinion about testing ("The step-by-step nature of class components encouraged testing practices, as we had to address each component's lifecycle events and behaviours individually.") Testing components with multiple useEffects is a totally different journey!
Thank-you Ola! Yea i'm really hoping to open up a conversation. Any recommendations for testing multiple useEffects? đ
My first thought about recommendations in this case is: run away! XD
But if we're being honest I would start by trying to build a mental model of how the component works, maybe try to write down a flow diagram. Then try to figure out what exact behaviour you're testing :) Because, as papa Dodds always says: Don't test implementation details!
( kentcdodds.com/blog/testing-implem... )
Is this a group letter? I can sign myself up under it! :D Really nice read.
One note I'd add from myself regarding the "TypeScripting our way to a stronger relationship!" - it has 2 sides - get grip of TypeScript, that's for sure, but because TS is becoming a default choice in more places everyday don't forget the basics - JS is under the hood and we all should understands how it works, so it's not all magical to us đ
Absolutely great callout! Theres so many great articles on JS best practices too :)
I found this a wonderful read.
If your poking at Gen Z with the dont think just do model, I would say sadly... that your right, but not necessarily for the right reasons.
If we read into the generation that grew up with an automatic music playlist, the ability to call whenever they were running late, and entertainment choices spoon feed to them, It's not hard to say they are the dont think just do generation.
This is exactly what the hooks architecture is, It's any loosey goosey model you want, without the need to organize the lifecycle. Not necessarily bad, but definitely risky.
Wow, this post is wonderful.
So well written, empathetic, and just plain old interesting! Also, the image breaks had me cracking up. đ
Really appreciate you sharing this with us! As a non-dev, it was so engaging and well written that I still found it fairly easy to follow (not to claim that I understand all the technicals, haha)... and now I feel like I've learned a little something new about how React evolved and why there is this sorta generational divide between how to do things. Thankya!
Thank-you so much for your kind words! Hopefully if you ever do give React a try you'll have some more empathetic "older" folks helping đ
Nice article!
And the pre-ES6-class generation before us deserve a shout out too! đ
There's something to be said about differences in testing approach that shifted massively between these generations. While now implementation details tend to be less tested, I feel coverage can be a bit more "gappy" if not careful. Or to avoid this, we tend to go overkill which requires more expensive levels of testing and more setup, which can require more maintenance in itself.
Great points! Yea I definitely think there could be a whole article dedicated to testing!
This is an incredible read! Thank you @anishamalde for taking us on this journey
Thank-you glad you enjoyed :)
Woah!! so many memories are coming back to me of early ReactJS. Thank you @anishamalde for such a fun yet full of knowledge blog for ReactJS future gen
Writing this made me realise, I definitely do not miss class components đ
good good stuff. Thank you
Thank-you!!
Some comments may only be visible to logged-in visitors. Sign in to view all comments.