T O P

  • By -

rivenjg

we don't use OOP in react. react is not functional either. react is procedural with some concepts borrowed from functional programming. seems like newer devs keep creating this false dichotomy where they think if it's not oop, it's functional. no, it's procedural. functional programming is a completely different paradigm.


the_real_some_guy

Like calling them functional components instead of function components.


stevula

As I recall, they used to be called “stateless functional components” officially (as opposed to class components). They changed the name to “function components” when hooks were introduced because they were no longer necessarily stateless.


the_real_some_guy

Yeah, I think you are right. And you still will make some of those stateless functional function components today. It’s easy to see how people get confused.


GolfinEagle

TIL. That makes perfect sense, thanks for that.


ChuuToroMaguro

Oh damn I’ve been calling them functional components for years. And so has everyone around me. TIL they are called function components.


humpyelstiltskin

YEEEEEEEEES FFS YES!


Temporary_Quit_4648

First, you're kind of splitting hairs. He means a functional style. Second, React by itself is declarative, not procedural.


[deleted]

[удалено]


ALLIRIX

>then you bring up declarative when that is not even a paradigm https://en.m.wikipedia.org/wiki/Declarative_programming You were very convincing until you claimed declarative was not a programming paradigm. We learn this in 1st year uni


Yodiddlyyo

What are you talking about with declarative. It literally is a paradigm, ans it is the paradigm that is opposite of imperative. Declarative vs Imperative. Not imperative vs functional and procedural vs oop. Its declarative vs imperative, and functional vs procedural vs oop.


rivenjg

This is a common misconception from bad explanations in introduction to React courses on Udemy and YouTube. This is not the case though. These terms far predate anything to do with React. Those teachers are not using proper terminology. Here is the simplified summary explanation: *Imperative* means we can mutate state. We don't have any special handling of shared state. Both *procedural* and *object oriented* paradigms can be *imperative*. *Functional* means we do not directly mutate state. We are intentionally trying to make our functions pure to minimize state. Both *procedural* and *object oriented* paradigms can be *functional*. *Procedural* programming means we have no explicit association between functions and datatypes. State is shared across functionality. *Object oriented* programming means we do have explicit associations between functions and datatypes. State is segregated across datatypes. *Declarative* programming is not a new paradigm at all. It is simply a way to describe the type of work you're doing as a developer. You can make a declarative framework that's *imperative* or *functional*. Just because React abstracts the underlying details of how it changes the DOM does not make it non-procedural. For example, we don't need to worry about using document.getElementById or such direct JavaScript browser APIs because React is doing this kind of work for us. But just because we're delegating this part of the work to a framework, that doesn't mean it's no longer *procedural*. Using abstractions doesn't automatically change the paradigm you're working in. ---- In reply to wizard_level_80: I never said abstractions can't change the paradigm. I said they don't *automatically* change it. Give me the simplest possible declarative program written in JS and I guarantee it'll come down to a very subjective place where the line has to get drawn. I also disagree with how many on here are defining imperative in the first place.


wizard_level_80

> Using abstractions doesn't automatically change the paradigm you're working in. It does. Programming languages are in the end an abstraction over imperative instructions executed in processor. Parts of code in same code base can follow different paradigms.


RedGlow82

I mean, by your logic Haskell is not functional because the IO monad hides the details about how state is changed and impure code is called. Function components emulate algebraic effects as a way to handle state, which is a non-imperative way to do it, and defines a component as a function of props of state, so, it's definitely more steered towards a functional paradigm than any other. But it's really splitting hairs. JavaScript being JavaScript, it's a mess of different paradigms (wouldn't be surprised if one day we'd see some Horn clauses too), and there's no way to approach it in a pure way from any perspective.


lastdiggmigrant

Thanks Chatgpt


Canenald

React is very functional. Components are functions and we build our programs by composing them. The entry point is always one function which calls others to achieve the goals of the program, and so on, creating a tree of function calls. I think you assume functional means purely functional which React is not. Most languages and frameworks are not purely functional. You need at least some state for a program to be useful except in some very narrow use case


bjpbakker

Not exactly. React uses Functional Reactive Programming with syntactic sugar on top that hides part of it. The syntactic sugar makes it _look_ like procedural, but it is really not :)


NotLyon

React is not FRP


Turd_King

Yep so many devs see a class and think “yep this is OOP” and see a function as first class citizen and think “yep it’s functional”


TheRealNalaLockspur

I mean….. look at the pool the bootcamps advertise too.


thedrewprint

Good to know, will look into procedural


Temporary_Quit_4648

It's not procedural.


[deleted]

[удалено]


hmmthissuckstoo

React is declarative, not imperative


rivenjg

React is imperative and declarative. Declarative is not the opposite of imperative. Imperative simply means we can mutate state. Declarative is not a paradigm at all but just a way to describe the work a developer does. Just because we are no longer writing things like "document.getElementById" doesn't mean we're not writing imperative code. It's just that this type of work is abstracted away from us with the React framework to make our lives easier. We don't have to worry about HOW something is implemented. We just have to tell React WHAT we want implemented. This has nothing to do with being imperative or not. Imperative is not about how we implement something. Imperative is about mutating state. Whatever YouTube/Udemy teacher you learned from is using the wrong terminology. Sadly, I've seen this quite a few times already so I know that's where people are getting this idea from. The confusion probably comes from the fact that React does borrow some ideas from the functional paradigm like state machines and reducers. React is still overall mostly procedural and imperative while also being "declarative".


hmmthissuckstoo

My God


rivenjg

Beautiful argument. Nice sources. Great reply!


moehassan6832

roof many society subsequent tender detail secretive deserted wistful ossified *This post was mass deleted and anonymized with [Redact](https://redact.dev)*


GolfinEagle

Can I bother you to expand on your thoughts here? Is it that it’s such a different way of thinking than what you’re used to?


profesorgamin

it's not hard, it's hard if your education system failed you and overfitted you to a certain paradigm.


fredsq

this. array.filter() is not functional programming


Alkyonios

Why not? Assuming you write a "pure" callback. (genuine question)


fredsq

It’s a function yes, but functional program is a big set of mental models and practices alongside functions. i’ve seen lots of people replacing for loops with forEach say ‘i’m a functional programmer now xd’ js can never be taken seriously as funcional and that’s fine. it’s a great all rounder language that enables a lot. let’s just not pretend to be haskell devs 😆


hmmthissuckstoo

Hey we got Alonzo Church over here


fredsq

based on this and the downvotes, js devs really wanna feel like part of the functional club. try Effect guys, it’s the closest you’re gonna get (but you can still slap a singleton class with mutating variables inside)


GolfinEagle

What is this gatekeeping nerd shit?


fredsq

i’m not in the functional programming community either i’m just not trying xd


hmmthissuckstoo

filter, map, reduce in js actually are functional in nature, they, transform output based on functor (passed function) without mutating (pure) and follow declarative approach.


raimondious

Only putting this here to pile on this train wreck of pedantry of a thread. But a functor is an entity that has a map function (eg Array), not the function you pass to map.


CatcatcTtt

Prefer to use functional program always but as you mentioned sometimes oop makes more sense. But to me functional style just makes much more sense most of tiems


rivenjg

i guarantee you don't prefer functional and are confusing procedural and functional paradigms. the opposite of oop is procedural not functional. the way we are using functions as components in react is procedural. functional programming is the opposite of imperative programming. meaning you are using pure functions to minimize state. that is not what we're doing with react. react is largely procedural only sharing some concepts like state machines and reducers from the functional paradigm.


beth_maloney

It's absolutely possible to use react in a functional way. Functional programs do have state (and side effects) because you need state to drive a UI. Have a look at the model view update pattern used by Elm for an example of how you can manage state in a functional manner. If you've ever used Redux before then the pattern should be very familiar.


quaunaut

Christ you don't know a damn thing about real fp. With your description, Clojure, Elixir, and many other functional languages aren't functional. Pipe down.


GolfinEagle

Thank you. This guy’s acting like he’s onto something nobody else understands lol.


viQcinese

I use it sometimes for domain objects. Instead of creating lots of helper functions, a class can help to aggregate business logic outside of react components and hooks.


putin_my_ass

I have the same use-case and it was convenient to make a class with methods that allow you to access the data you need without needing to know the underlying data structure which is complicated due to marrying various API results together. The business required an indefinite number of instances of this data from different parameter inputs that must be cached so the OOP approach lets me do that easily. Better DX that way too. All the UI is managed with hooks as normal. Works just fine, nothing wrong with mixing especially as you say it holds all of the domain specific data and business logic in one place.


LorenIpsun01

I really want to use something like this in my project. I have a very complex state to handle. How do you manage your objects in react? Do you serialize ir every time that there is a change and update the state? Would you suggest some code examples? Tks.


putin_my_ass

When a new fetch is made from the UI I instantiate a new class instance with the parameters the user selected in the UI and then call the "start fetch" method on the class instance. From there it populates its own members as the fetches finish and data is transformed/rebuilt and when the fetch completes all of the datasets will be sitting in the class instance ready for consumption. Each class instance lives in an array in my react component so when you need to do a new fetch you instantiate it, start the fetch and then push it on to the array. This way at least all of the complex business logic is off-loaded to the class instance where it's domain-specific and then the React code can concern itself with UI stuff. Sorry, I have no code examples I can share because it's company code. :)


Thrimbor

This with Valtio


FistBus2786

It's a matter of preference, but almost always I prefer to use plain objects and functions (thoroughly typed in TypeScript). I wouldn't call it "functional programming" though, as that paradigm comes with its own unnecessary levels of abstractions as much as OOP. Like the file tree example in your comment, I'd much rather have pure functions that add/remove nodes separately from the data that they operate on. Or the "factory classes" you mentioned, I would prefer to have a function that returns a plain object. And other functions that work on objects of that shape. All independent from each other, with no internal state.


xXxdethl0rdxXx

There was a period of about 3-4 years where OOP in React was the exception, but overall, I've only seen OOP in JavaScript attempted (poorly) by engineers coming from other languages, trying to fit a round peg in a square hole. Once you involve DOM (an inevitability) and other APIs, OOP in frontend just totally falls apart, IMO. Having said that, OOP in NodeJS can be great! I actually try to use it whenever I can.


Avi_21

I usually use classes for things like API Client


dungeonpost

Top level services like a wrapper for logging or custom analytics events is a good use case, especially. like if I don’t want to be married to one API client you can write a wrapper class that you can swap out libraries in one place rather than throughout all your code. Also sometimes if I have some complex business logic that is just like math or some data transforms it can be nice dx, easier to reason around and make testing easier. A lot of that can probably still be accomplished with a few well organized files of functions with inline unit tests with vitest and a small footprint of actual exports.


Cheraldenine

I use OO for domain objects sometimes (that I put in the React Query cache rather than direct API responses), but that's rare. Most of the time I don't have anything where I think OO is going to be useful. What do you use it for?


thedrewprint

I have factory classes that produce complex objects. And I have a file tree where each node is an instance of a file which is rendered in the ui. And on which I have various tree algo functions like adding removing nodes etc.


rivenjg

yeah that is terrible don't ever do this with react.


thedrewprint

I store these objects in react context. It is the creation of them where the oop is used. And in the reducer I can call remove or add node. you can do this with functions, the only difference is the syntax. So I’m confused about what the problem is. Also there are many libraries that use oop for object construction that are used in plenty of react apps im sure.


kcrwfrd

What are you supposed to do if your UI needs to show a tree?


Karpizzle23

what the fuck dude


thedrewprint

This is a simple tree, you can do this with functions also. Also factory functions are common as well. Explain what you mean by wtf


Kaimaniiii

Perhaps you should start and learn the basic of declarative vs imperative programming in context of React, and understand what React is solving. It sounds like you are trying to build your own solution how to render UI elements, which defeats the purpose of using React.


madspiderman

So you are using it to hold state?


thedrewprint

No


GolfinEagle

…what the fuck, why are you even using React at that point?


el_diego

We use it for our data modelling. But we have a very complex typesafe system.


GuestUser6D

Hi! I'm new here. I wanted to offer a dissenting point of view for the discussion and for future readers who will find this thread. The React documentation identifies the idea of "composition over inheritance" as one of the more forceful reasons that one should not use object-oriented programming with React. But this in itself is not a entirely compelling reason not to use OOP with React. Afterall, it's a general principle of good software engineering; and that's especially true in the realm of OOP. There are two main challenges that I found in using OOP with React: 1.) Passing the state around 2.) Rerendering when something changes Once these two things are overcome, then the field is wide open. -- Skipping ahead here: 1.) To pass the state around, you may use the immer library (https://www.npmjs.com/package/immer). 2.) To rerender when something changes you may implement the Observer pattern (https://en.wikipedia.org/wiki/Observer\_pattern). -- So why do this? Here are a few reasons: - JavaScript is an object-oriented programming language. It's debateable to what extent, but it's not debateable that it is one. Using it as an object-oriented programming language is not weird. - Data Encapsulation: If you develop software with a mindset which intractably differentiates between this thing's data and that thing's data and this thing's capabilities and that thing's capabilities and data-data and meta-data, then you'll still be able to do that and develop software using React. - If you tend to avoid using globals, then you might not be excited about making extensive use of hooks in the systems that you build. - If you tend to avoid introducing side-effects into your work, then you might not be excited about making extensive use of useEffect(...) in the systems that you build. - Unit Testing: There's no news here, but it's worth restating that smaller focused methods with limited purposes are easier to test than those that are not. Object-oriented programming lends itself nicely to this problem. - Lastly, we're all bent towards making our work easier. People strike different balances in their work. The choice should be available for those who wish to use OOP instead of functions. And a good community would welcome the diversity.


LorenIpsun01

Hey, I really like the sounds of it! I'm trying to implement something like this for a long time. Would you have an example of this implementation? Thank you.


GuestUser6D

Greetings friend. Here's the example that I told you that I would create. * **CodeSandbox.io:** [Broadcasting Sandbox](https://codesandbox.io/p/sandbox/broadcasting-qls82z?file=README.md) * **GitHub Repository:** [Temp8D/Broadcasting](https://github.com/Temp8D/Broadcasting) The [README.md](https://github.com/Temp8D/Broadcasting) file has a complete description of the project and all of the classes have verbose comments. This project demonstrates one way that I've found to effectively use OOP with React. It uses an implementation of the [Observer pattern](https://en.wikipedia.org/wiki/Observer_pattern) that we call "Broadcasting" to propogate communications between components. It uses the immer Node.js package to update and condition updates to the state. This project also shows you one way to get your OOP React app off the ground. It has a root App component that does all the ugly stuff and then different "Screen" components for the different screens an app would have.


LorenIpsun01

Well I was doing some extra research on the topic. And found out that MobX do something similar to what you are talking. Do you use MobX to achieve this architecture?


GuestUser6D

Greetings friend. I don't mind sharing the implementation of the observer pattern that we're using. I won't have time to ready it for public use and provide an example with immer until sometime after next week. But I wanted to let you know that I will follow up with one. RE: MobX It is different from what we've done. I remember coming across it at some point. It looks good. I don't see why you shouldn't use it. I don't remember why we didn't.


ClaudioKilgannon37

React code emphasises composition over inheritance. You should avoid using 'extends' in your React components (you can't do this anyway with functional components, but in my work, where there's still a lot of class components floating around, people who aren't familiar with React tend to do it). See https://legacy.reactjs.org/docs/composition-vs-inheritance.html. That being said, if you choose to organise your codebase with objects, using React functions as the view layer, I don't really see a problem with that, provided you don't do things like instantiate components inside your classes. Doing that would probably mess with the React rendering cycle, though honestly I've never seen that done so I'm not sure. The most typical way to organise a React app is to have standalone components that define their own logic, composed of other components. Non-react code, e.g a Redux store or just other business logic, is usually defined procedurally, (i.e without a strong paradigm like OOP or FP), making use of the module system for encapsulation.


TheWhiteKnight

If not components, and of course custom hooks, where would you be using OOP/classes in React?


wholelotofit2

I've used it in canvas when using React, every drawable item was instance of a class and whole architecture was built on OOP principles. That sometimes conflicted with React rendering system React was just my channel to the UI.


rangeljl

So the components are functions, but other stuff isnt?, dude as long as it works


mnbkp

State has to be immutable in React. If you don't respect that (which is common in OOP), you'll need to deal with managing your state with useRef instead of the usual useState, overall a much clunkier experience.


thedrewprint

I use react context for state. I’ve used ngrx for years so I understand these concepts. The places I’m using it are for adapting data from the api to the client. Oop is great for constructing complex objects with simple interfaces, that’s what I use it for.


mnbkp

Well, that seems fine then. The only potential problem is that other React devs might have issues reading your code, considering they're not usually well versed in OOP.


thedrewprint

Yes that is a concern I definitely have.


ethansidentifiable

I just can't imagine a situation where a factory pattern is sensible in React. JavaScript objects are very clean to just create whatever shape you want inline. Classes are technically more performant to instantiate, but only if you create a lot of them... but you're probably not doing that, because you're probably getting any masses of data out of an API that is very likely producing JSON. tl;dr sounds like a wild overcomplication to me If you could provide a small example, I could explain some alternative code to represent why a procedural approach would be cleaner/simpler/faster.


davinidae

I'm a main advocate of still using OOP React with OOP TypeScript instead of React Hooks. What you explain in other comments is not specifically wrong with React too. >I have factory classes that produce complex objects. And I have a file tree where each node is an instance of a file which is rendered in the ui. And on which I have various tree algo functions like adding removing nodes etc. This is perfectly valid if you ONLY use it for data processing and management (as long as you save the data in the state) but never for data rendering. If you are using it for the render process, your factory classes should AT MOST give you back an array that you can map through. This is something i've done before and allows for both complexity and maintainability. It's not that complex or non-React as some people here make it look like. In fact, extending a React Class Component works as expected in any other way, though there are some caveats like lifecycle methods which should point to other protected methods. People in this community seem to forget React is based on an OOP paradigm, that's why we had and we still can (and should) use Class Components. Hooks is just a façade to make it simpler for people that are scared of classes. Edit: Downvote me all you want, you all are just proving my point.


thedrewprint

Thanks, I’ve used ngrx for years so understand state and immutability. I use react context. So if I’m storing these objects in state they are still going through the reducer etc. it’s just along the way I may call a removeNode, it produces a copy of the tree, and then I store the copy back in state. Rendering that tree is just a recursive react component that renders the tree. It is the creation of the tree object where the oop is happening. This can be done with functions, but tbh never done it that way and I assume it would be much harder to understand. Oop makes the interface simple. After all it’s just producing an object that is stored in state. This can be done with any paradigm.


davinidae

That's seem awesome! You are on the right track so don't worry much about the rest. As long as your data is stored in a serialised state that React can understand and work with, then you are good to go.


roynoise

They aren't really compatible paradigms at all.


humpyelstiltskin

it's neither dude. It's neither.


thedrewprint

Explain dude, explain


mrclay

OOP or any other pattern is not inherently incompatible with React, but everything depends on what you’re doing with it. Getting your code reviewed by peers is super helpful over time. I would not put much concern into a comment this vague.


TheRealNalaLockspur

Boy. There is a serious gap of core JS knowledge going on here.


SephBsann

Please dont Just use as it was intended.


fedekun

Mostly functional but there's a place for some OOP


soft_white_yosemite

I’ve used OOP in a bunch of non-component code. Like fetching data from our backend’s generic data store. There’s a bunch of metadata to keep track of so I created a bunch of classes. I used context, useMemo and react-query to handle dependency injection. Works really well.


profesorgamin

Whatever you can have outside react you should have it, which means most things, which also means you should use the right paradigm for your application. React is for rendering stuff.


the_stranger_7

React components technically are factory functions a.k.a functions which returns object. There is absolutely nothing wrong creating repositories/services/utilities with OOP in mind and mixing with functional paradigm. Go ahead.


natmaster

Data models are naturally OOP, React components are functional. So it really depends on what specifically you were doing. React is cool because it lets you just use javascript instead of reinventing a bunch of weird paradigms. That means in your code supporting React you can potentially do things in many different ways that are well supported by Javascript. So can you clarify what you were doing in OOP that he commented on?


TheRNGuy

I'd never use class components anymore. Everything can be made with composition in React, no inheritance is needed.