You think you learnt functional-reactive JavaScript on some online tutorial?
You might actually have learnt imperative-reactive stuff claiming to be functional, or functional-reactive, when in fact it's not.
This article will teach you how to tell the difference.
Myth: If you're doing React functional components, you're doing functional-reactive programming.
Reality: This term only refers to the way a component is created, which is by means of a function and not a class. It has nothing to do with either functional or functional-reactive programming. React is an imperative library.
Let's continue with the typical pattern of an imperative-reactive piece of code:
// One imperative approach
let value = 1;
value = 2;
// Another imperative approach
const [value, setValue] = createState(1);
setValue(2);
Every time you set a variable as above, you're performing an imperative change. (React hooks, Angular signals, SOLID signals, Svelte scripts anyone?)
The functional approach, though, starts by defining an entity as a function of a source. In other words, assign a function to a target:
// The functional approach
const target = someFunctionOf(source);
In this case you never directly set the value of target
in any way.
So what if source
changes somehow? That's where reactivity steps in.
In JavaScript one if not the best way of making code both functional and reactive is using Observables:
// A functional-reactive approach, where state
// is defined as an Observable stream.
const state = new Observable(observer => {
observer.next(1);
setTimeout(observer.next(2), 1000);
});
// So this is how you make use of it
state.subscribe(console.log);
Here state
is defined as an Observable, so you will need a sink to display changes somewhere, like the DOM, the console, the network, or something.
These examples are obviously oversimplified, but should show a way to easily tell imperative-reactive code from functional-reactive.
Functional JavaScript
So, what is functional JavaScript, then?
It's functional, but not necessarily reactive. With the use of functions, some composition, such as map/reduce, but only executed once on a source stream. If the source updates, the result does not.
const source = [1, 2, 3, 4, 5];
const result = source
map(x => x*2)
reduce((a, b) => a+b, 0)
;
The above is a simple example of functional, non-reactive JavaScript code, where result
is calculated once, but immutable, since it's a constant value.
Essentially, all this is, is the use of some principles from the functional programming paradigm. JavaScript is multi-paradigm, so it allows you to combine concepts and structures from object-oriented, procedural, functional paradigms and use them at your discretion.
Functional JavaScript in particular is what you can do with map/reduce, (meh, callbacks) promises, observables. The last of these is what really brings you reactivity.
Additionally, there are certain principles, like function purity, that are not reflected in any language construct, but are more like a design pattern that you may choose to follow in order to make code more testable, robust, and free from bugs.
Conclusion
The easiest way to compare an imperative vs a functional approach is target=value
(which is the same as doing setTarget(value)
), vs target=fn(source)
.
Top comments (0)