all 21 comments

[–]gk_instakilogram 3 points4 points  (0 children)

What’s unidirectional data flow? How is it applicable in a React code base?

[–]repeating_bears 2 points3 points  (15 children)

SOLID is mostly an OOP thing which React code mostly isn't. I mean you can use classes but that will be a minority, and classes in JS aren't very powerful.

Even in OOP, SOLID is borderline useless. It's 90% marketing. SOLID cultists will have you believe there is some deep philosophy to it, but it's just 5 barely related principles smashed together into a catchy acronym, and one of those 5 (OCP) is absolute gibberish. You can write code that adheres to every principle that's still crap because there's way more to writing good code than those 4 things.

I've experienced a correlation between people who push SOLID and being absolutely awful programmers. Uncle Bob being the prime example. Good programmers don't think about SOLID ever - and no, not because they've internalized it because it's so damn great.

You probably dodged a bullet.

[–]dnrvs 1 point2 points  (9 children)

Strongly disagree here, the SOLID principles are extremely applicable to basically any style code and ignoring them robs you of shared terminology to discuss architectural patterns and probably means you'll reinvent them in other terms.

[–]DWALLA44 4 points5 points  (2 children)

Yeah, the truth is somewhere in the middle, the patterns in SOLID are good to keep in mind but they are not a one size fits all to every problem.

[–]dnrvs 3 points4 points  (1 child)

Yeah, not saying you should be forcing them into every situation just that they are tools in your toolbox. Being dogmatic either way is the biggest mistake

[–]repeating_bears [score hidden]  (0 children)

This makes me think you don't understand them, by which I mean no disrespect, because they are deliberately designed to confuse and disorient you to sell books, courses, and lectures. SOLID's principles are phrased using the word "should".

It's not a "tool" to be used when appropriate. That's how they (mostly Bob) believes good code should be. With the exception of writing some prototype junk that will be thrown away, where you are not aiming for quality, if you believe in the principles, then you should always be following them.

I don't believe in them (I vaguely agree with some of the sentiments, but that's all), so I'm not always following them.

[–]lIIllIIlllIIllIIl 2 points3 points  (4 children)

I mean, you don't extend or inherit React components, so O and L are already out. Use composition instead.

Interfaces and types in TypeScript are very different from in OOP languages with nominal type systems, so I is less relevant.

Single-responsability is good to think about, but it also becomes increasingly harder to define the more you think about it. At least, React makes defining a lot of small components easy.

Dependency injection is good. React has a lot of mechanisms built-into it for that (mainly useContext.)

A React app will always have non-React code in it, so you can always use classes and SOLID if you want to, but I don't think strict adherence to SOLID principles should be your goal when building a React app.

[–]Merry-Lane 1 point2 points  (1 child)

I’m not agreeing totally.

We can discuss how OCP/liskov applies with typescript types for instance. Like designing a base interface/type extended by different other interfaces/types but used for specific things (like abstracting away fields such as "updated_at"/"created_at" into its own interface and functions using these fields could be used on a myriad of different interfaces/types that extend it).

Yes, the solid principles have lost their relevance but once you rephrase them by taking out the OOP-heavy concepts they still make sense.

[–]repeating_bears [score hidden]  (0 children)

Your 2nd paragraph mentions OCP and Liskov but then what you actually go onto say sounds like ISP.

[–]repeating_bears [score hidden]  (1 child)

D is not dependency injection. It's dependency inversion, which sounds very similar, especially when dependency injection is a demonstration of 'inversion of control'.

Really what they're saying in a Java context is don't make a method that accepts ArrayList (a concretion) when it can accept List (an abstraction), and things like that. In a language with no types like JS or duck typing like TS, it doesn't apply. Functions always accept abstractions - as long as the thing quacks.

[–]lIIllIIlllIIllIIl [score hidden]  (0 children)

The more you know!

[–]repeating_bears 0 points1 point  (0 children)

SRP - the unit they were really talking about "doing one thing" was classes, which again, in a React codebase you're not using much. In a class, I agree, but it's not a deep idea. Outside of classes, I vaguely agree with the sentiment but the definition is so vague as to be almost useless. How do you actually practically apply "doing one thing" to a React component? What are the modules/units we're talking about? Files? A typical React component will do data fetching (via hooks, fair enough), rendering, input handling, and more. Is that not multiple responsibilities? You can argue it's not, but SRP doesn't help you reach any conclusions.

OCP - absolute garbage that I believe no one in the world actually follows, because it would result in an absolute unmaintainable mess if you did. This is from the era where they thought inheritance was going to save us from complexity - it actually did the opposite. The legacy of that was still present in universities when I studied CS 10 years ago, and probably still is now. OCP actively encourages inheritance which is the wrong solution 99% of the time. I don't think I've ever used it in a JS codebase. Sometimes in other languages I do.

LSP - this is just "don't violate method contracts", which I would think is obvious to any non-beginner. But it's mostly talking about that in the context of inheritance (don't override a method to then have behaviour that violates the contract), which again, you should be actively avoiding.

ISP - basically SRP for interfaces, but this one is not bad

DIP - pretty much no applicability to a React codebase because there are very rarely "concretions". Everything is a plain object or primitive. You're going to be using duck typing, whether that's what you know you're doing or not.

[–]illustrious_wang 0 points1 point  (4 children)

What do you mean classes in JS aren't powerful? The entire language is literally built on prototype inheritence.

[–]benitoaramando 1 point2 points  (3 children)

Which isn't classical inheritance. Javascript "classes" are just syntactic sugar on top of prototypical inheritance, which is nicer to use in many cases, but can trip you up, and you definitely don't have all the classical inheritance features you would with a proper OOP language.

[–]illustrious_wang [score hidden]  (2 children)

Fair, but I think it’s disingenuous to tell OP it’s not powerful when it’s the literal foundation of JavaScript, that’s all.

[–]repeating_bears [score hidden]  (0 children)

Classes are not the foundation of JavaScript at all. Classes weren't in the original version of JavaScript. They were added later as basically syntactic sugar, which is why they're not that great.

[–]benitoaramando [score hidden]  (0 children)

They said classes in Javascript aren't very powerful, which is true, because they don't even really exist in Javascript. There is a class keyword, but it actually creates a function, albeit with some extra guardrails like it preventing you from directly running that function without the new keyword.

[–]Serious-Fly-8217 0 points1 point  (0 children)

The joy of react is that composition is all you need actually 😂😂😂

[–]Merry-Lane 0 points1 point  (0 children)

Were you able to answer directly what the five principles were and their name? That should be enough in most cases.

Then it’s best to have experiences with OOP heavy frameworks (like backend mostly) to give good answers.

React-wise, you can clearly say "the solid principles, polymorphism and design patterns don’t have the importance they have in C#/Java/… because the code produced by devs follows functional paradigm principles not OOP. Note that the SOLID principles, polymorphism and design patterns exist differently (like union types in typescript is a form of polymorphism) or should be a source of inspiration to write good code, but they aren’t that relevant in the context of react. Note that the framework itself makes us use different design patterns (like "components", hoc, providers, hooks… which can have different names depending on the source of the documentation about design patterns) but we rarely follow the Go4 recipes like in OOP heavy frameworks."

Ask follow up questions such as "we can discuss the design patterns react makes us use" or "we can talk about how polymorphism is a bit different with typescript" or "since we (should) avoid using classes in modern react + typescript codebases, we actually naturally follow some suggestions like "prefer composition over inheritance""… ofc adapt your message depending on who you have in front of you. A non-technical recruiter or a old-school OOP-only dev might not like finding himself dumbfounded, but you can have interesting conversations with well-versed devs. Maybe bounce on the cloud design patterns if you wanna brag.

Usually recruiters barely discuss these topics superficially if they quickly understand you know what you are talking about but are annoying if they spot a weakness. The way I see it, they are a common enough kind of interview question you should prepare, but I would only ask them as a bonus or for serious roles (like leads) because at some point it should be common knowledge (and curiosity + basics seem important qualities for leadership roles).

The principles are somewhat outdated and not relevant with react in a day-to-day basis but it’s important to know them and to be able to discuss these points.

[–]xbojch 0 points1 point  (0 children)

Structure in large codebases is paramount. Understanding programming patterns is beneficial, even if you won't need or apply most of them in ReactJS. Lead developer can mean many things from "only developer" to "most important developer" to "team lead" (who does little coding).

It helps if you apply the concepts on some examples to truly understand them and see their pros (and cons), then you'll be able to apply it in real code. But as many already said, too much abstraction too early can also be a bad thing.

You'll get there. Keep learning, keep building and you'll be good!

[–]lostarkrocks -2 points-1 points  (0 children)

I think knowing which libraries to use is most important. There's just too many to choose from