Functional React, 2nd Edition
By: Cristian Salcescu
Tags: JavaScript, React, Functional Programming, Programming, Front End Development

Quick start with React Hooks, Redux and MobX

If you want to learn how to build modern React applications using functional components and functional programming principles, this is the book for you.

React allows expressing the UI using functions. React Hooks enables stateful functional components.

Here are some of the things you will learn:

The core functional programming concepts with JavaScript

How to create components using only functions

Presentations and container components patterns

How to use the state and effect core hooks

How to create and reuse a custom hook

Discover both Redux and MobX as state management solutions

How to handle side-effects with both Redux Thunk and Redux Observable

Using the React Router to enable routing in single-page applications

How to structure React applications

Programming in a functional style means to use concepts such as pure functions, immutability, closures, higher-order functions, or currying.

Chapter 1 Functional JavaScript

One great thing in JavaScript is functions. Functions are treated as values. We can simply define a variable, storing a function. Here is an example:

const sum = function(x, y){

return x + y;

} sum(1, 2);

//3

The same function can be written using the arrow syntax as follows:

const sum = (x, y) => x + y;

We favor declaring functions using the const keyword instead of the let keyword to prevent its modification.

Like other values, functions can be stored in objects, arrays, passed as arguments to other functions, or returned from functions.

Pure Functions

A pure function is a computation. It computes the result using only its input. Given a specific input, it always returns the same output.

A pure function has no side-effects. It does not use variables from outside its scope that can change. It does not modify the outside environment in any way.

Pure functions have a big set of advantages. They allow focusing attention in one place, the function itself without its surrounding environment, and that makes it easier to read, understand, and debug.

Immutability

An immutable object is an object that cannot be modified after it is created.

Immutable objects can be created using Object.freeze() .

const product = Object.freeze({

name : 'apple',

quantity : 1

}); product.quantity = 2;

//Cannot assign to read only property 'quantity'

Object.freeze() does a shallow freeze and as such the nested objects can be changed. For a deep freeze, we need to recursively freeze each property of type object. Check the deepFreeze() implementation.

Changing an immutable value means creating a changed copy. For example, if we want to modify the quantity of the previous product , we create a new object.

const newProduct = Object.freeze({

...product,

quantity: 2

});

The spread syntax is helpful when creating copies of objects.

In functional programming, all the data transferred between functions are immutable or at least treated as being immutable.

Functional Array

In the functional style, we get rid of the for statement and use the array methods.

Before going forward, note that primitives, objects, and functions are all values.

const numbers = [1, 2, 3];

const total = numbers.reduce(sum, 0);

//element=1, total=0 → result=1

//element=2, total=1 → result=3

//element=3, total=3 → result=6

//6

Chaining

Chaining is a technique used to simplify code by appling multiple methods on an object one after another.

Below is an example where the filter() and map() methods are both applied to an array:

const numbers = [1, 2, 3];



const stars = numbers

.filter(isOdd)

.map(toStar);



//['*', '***']

Closures

Closure is an inner function that has access to variables from outer function, even after the outer function has executed.

Consider the next example:

function createIncrement(){

let count = 0;



return function increment(){

count += 1;

return count;

}

}



const doIncrement = createIncrement();

doIncrement(); //1

doIncrement(); //2

doIncrement(); //3

increment() is an inner function and createIncrement() is its parent. increment() has access to the variable count from its parent event after createIncrement() has been executed. increment() is a closure.

Higher-order functions

A higher-order function is a function that takes another function as an input, returns a function, or does both.

filter() , map() , reduce() are higher-order functions.

Currying

Currying is the process of transforming a function with several parameters into a series of functions each taking a single parameter.

Currying comes in handy when aiming for pure functions. Consider the next code:

const fruits = ['apple', 'mango', 'orange']



const newFruits = fruits.filter(function(name) {

return name.startsWith('a')

})

Now, let’s refactor out the filter callback to a pure function with an intention-revealing name.

function startsWith(text, name){

return name.startsWith(text)

}



const newFruits = fruits.filter(name => startsWith('a', name))

As you can see, startsWith() has two parameters and filter() needs a callback expecting one parameter.

We can write startsWith() as a curried function:

Currying

Currying is the process of transforming a function with several parameters into a series of functions each taking a single parameter.

Currying comes in handy when aiming for pure functions. Consider the next code:

const fruits = ['apple', 'mango', 'orange'] const newFruits = fruits.filter(function(name) {

return name.startsWith('a')

})

Now, let’s refactor out the filter callback to a pure function with an intention-revealing name.

function startsWith(text, name){

return name.startsWith(text)

} const newFruits = fruits.filter(name => startsWith('a', name))

As you can see, startsWith() has two parameters and filter() needs a callback expecting one parameter.

We can write startsWith() as a curried function:

function startsWith(text){

return function(name){

return name.startsWith(text)

}

}

Then, it can be called providing only one parameter, the text to search for.

const newFruits = fruits.filter(startsWith('a'));

Thanks for showing interest in this book!

Click here to get a sample of the book.