I\'ve been using object-oriented programming practices for 25 years and trying to move toward functional programming for the last 5 years, but my mind always goes towards OOP wh
This question is a bit opinion-based but let's concentrate on the core points.
There is no contradiction between functional programming and OOP. You just need to use the same programming patterns. There is no problem to use classes (with inheritance) in functional programming, if you keep them immutable.
To prove my point, the popular library Immutable.js that is used by many people to keep state in redux is composed from classes. And those classes have inheritance (e.g. OrderedSet extends Set
).
Also note that most React
components are classes and they use inheritance, too (... extends React.Component
).
The answer is that it's possible but heavily discouraged and non-idiomatic.
React does rely on classes and single-level inheritance of React.Component
to implement stateful components with lifecycles, but you are officially discouraged from doing further levels of inheritance in components.
Redux is built around Functional Programming principles. For a variety of reasons, you are encouraged to keep your state as plain JS objects and arrays, and access/manipulate it using plain functions.
I've certainly seen many libraries that tried to add an OOP layer on top of Redux (such as classes whose methods are turned into action creators and reducers). Those work, but are definitely going against the overall spirit of Redux.
I do actually use a library called Redux-ORM, which does allow you to define Model classes that act as a facade over the plain JS objects in your store. However, unlike many of the other libraries that I've seen, it works with Redux rather than trying to change how Redux behaves. I discussed how Redux-ORM works, how I use it, and why it's still reasonably idiomatic, in my blog posts Practical Redux, Part 1: Redux-ORM Basics and Practical Redux, Part 2: Redux-ORM Concepts and Techniques. Overall, it's an excellent tool for helping manage relationships and normalized data in your Redux store.
Finally, I'm currently working on a blog post that will discuss the actual technical limitations that Redux requires (and why), vs how you are intended to use Redux, vs how it's possible to use Redux. I hope to have that up in the next week or so - keep an eye on http://blog.isquaredsoftware.com .
I'll answer my own question by describing what I ended up doing, imperfect as it is.
First, instead of regular ES6 class syntax, I've started using stampit, which is uglier that ES6 classes, but much more flexible.
Mainly, though, my complex objects exist in two forms:
I use a convention of putting an _underscore in front of all references to the plain objects. My "solution" is kludgy and bad for lots of reasons, but I think trying to use selectors for everything would be worse. If you're curious, here's the place in my code where I "inflate" my plain store objects into instances: https://github.com/Sigfried/vocab-pop/blob/localstorage/src/ducks/conceptSet.js#L292
Turning redux state POJOs into class instances (regular or stampit) is a terrible idea and someone should have stopped me long ago.
I probably should have accepted @markerikson's answer, and maybe the Redux-ORM thing is worth looking at, but I just wanted to say definitively, DON'T DO WHAT I DID. (I always think I'm so smart filling in the "gaps" of technologies I'm learning with clever hacks -- and then I spend painful months cleaning up the mess once I understand why that technology didn't include my hack in the first place.)
From Composing Software: An Introduction:
What we won’t do is say that functional programming is better than object-oriented programming, or that you must choose one over the other. OOP vs FP is a false dichotomy. Every real Javascript application I’ve seen in recent years mixes FP and OOP extensively.
Looks like there are good ways to think about combining FP and OOP, and it will, no doubt, use some immutable classes and composition without a lot of inheritance. This series on composition looks like what I needed to learn.