Key Functional Concepts in React you should know

Asad Ali
4 min readApr 6, 2021

--

Due to the component-based nature of React and with the introduction of React hooks, the functional programming paradigm is becoming popular among react community. By seeing all components more as more functions than state carrying objects and the popularity of redux, there is an accelerated shift towards full functional approaches. The major advantages of this approach, include writing overall less code and easier debugging and testing since a pure function by definition produces no side effects. For large codebases, these features are really useful. Also, it forces us to focus more on writing immutable functions, which better support asynchronous programming paradigms. The below concepts, essentially, similar to classical lambda expressions used in formal math, produce no side effects and are stateless.

A classical function as per lambda calculus

For example:
instead of doing
x = 10
y = 2
z = x*y = 20
Do this instead , input -> compuatation -> output
f(x,y) = Lx*y.x,y = 20

The following are core concepts used in almost any react app

  1. Map

Apply something or some action to a list and then output the result


myArray = [2,3,4]
DoSomeStuff = (x) => (x + 100)
myArray.map(x => DoSomeStuff(x))
[200,300,400]
#general structure of map with index, array
const mapResult = myArray.map(function(val,index,array) {
console.log(val);
console.log(index);
console.log(array);
})

2. filter

Apply some filter condition on input/list and then output the result

MyCondition - I will filter a number whose sum with 15 equals 30
myArray = [15,4,3]
MyCondition = (x) => (x + 15 == 30 ? true : false)
myArray.filter(x => MyCondition(x))
15

3.includes

Compare in memory each element of the input/lists with the provided argument


myArray = [23,55,44,3,'ttert',343]
myArray.includes(23)
true
This however will fail for non-primitive types due to the way javascript stores objects
myArray = [{id:1},{id:33}]
myArray.includes({id:1})
false
Hence lets use
a1 = {id:1}
a2 = {id:33}
myArray = [a1,a2]
myArray.inclues(a1)
true

4. Promise

Promises are used to perform callback more effectively and avoid callback hell from repeated callback resulting from an action. Consider the following case

Vanilla CallbackGetSomeDataFromSomeWhere(Data, callback) {
if (typeof Data!== 'expected') {
callback(null, Error('Check returned Data'))
}
else {
DoSomethingWithData(Data, Error)
if (Error) {
HandleError(Error)
}
else {
DoSomethingWithData2(Data, Error)
......
// the code can have a lot nested sub-sections }# So As evident we can keep on calling these callback multiple nested timesInstead of passing callback, we create an abstracting called promise, which essententially will be an object which will return something in the future. We can then use this new object with "new" keyword to functions to handle the recieved information.const promise = doSomething();
const promise2 = promise.then(successCallback, failureCallback);
doSomething()
.then(function(result) {
return doSomethingElse(result);
})
.then(function(newResult) {
return doThirdThing(newResult);
})
.then(function(finalResult) {
console.log('Got the final result: ' + finalResult);
})
.catch(failureCallback);
Common promise pattern is using fetch function.
fetch('http://example.com/movies.json')
.then(response => response.json())
.then(data => console.log(data));
.catch(error => console.error(error))

5. find: Similar to filter, find the object where filter condition is met in the list

// Imagine searching through a large inventory for some itemconst inventory = [
{name:'Item1',qty:2},
{name:"Item2",qty:3},
{name:"Item4",qty:1}
]
function isItem1(Item) {
return Item.name === 'Item1';

}
console.log(inventory.find(isItem1))

6. Currying: Currying is a concept in functional programming, where a function takes instead of taking in multiple arguments, translates into a sequence of functions taking single arguments.

const currymultiply = (a) => (b) => (a*b)const curry5 = currymultiply(5)console.log(curry5(4))
//20
console.log(curry5(2))
//10
console.log(curry5(6))
//30

7. reduce: Reduce is among a family of functional programming concepts, where computation or logic is applied recursively to the input, the elements are recombined in some order and the final result is produced. So for example to add the list [1,2,3,4,5] we will recursively sum it and store the temporary values in accumulators and then output the final values.

sum([1,2,3,4,5])1. 5

--> 4+(5) = 9 (Stored in accumulator)

----->3+ (4+5) = 12 (stored in accumulator)

---------->2 + (3+4+5) = 14 (stored in acc.)

--------------->1 + (2+3+4+5) = 15

output = 15
const array1 = [1, 2, 3, 4,5];
const reducer = (accumulator, currentValue) => accumulator + currentValue;
//syntax
arr.reduce(callback( accumulator, currentValue, [, index[, array]] )[, initialValue])
//sum values of dictlet initialValue = 0
let sum = [{x: 10}, {x: 20}, {x: 30}].reduce(function (accumulator, currentValue) {
return accumulator + currentValue.x
}, initialValue)

console.log(sum) // 60 returned
//Slightly complex mapReduce to add even nos onlyconst mapReduce = (arr) => {const mapF =() => {
const mapFunc = () => {
var isEven = arr.map(function(val,index,array){
return ( 0 === val %2);
} );
return isEven
}
const reduceF = () => {
var tempvalue = acc.reduce(function(acc,current){
return acc + current;},0)
return [mapF(),redunceF()]}

8. Memorization or caching is an important concept in functional programming where we can store some objects in memory for later use.

// Lets say we want to perform a computational expensive operation such as raising by power of 100 some large numberconst raiseBy100= (x) => { return Math.pow(x,100)}//Calling the same thing multiple times simple causes unneccesary computationraiseBy100(100000)raiseBy100(100000)
raiseBy100(100000)
//instead we will caching to store the result in an objectlet cache = {
100000:10000000
};
const memo_raiseBy100 = (x) => { if ( x in cache) {
return cache(x);
}
else {
cache(x) = Math.pow(x,100)
return cache(x)
}
}

--

--

Asad Ali

Data Science, Analytics, and Machine Learning Professional.