Declarative programming
React offers a declarative approach makes it easy to use, and consequently, the resulting code is simple, which often leads to fewer bugs and more maintainability.
Exercise 1
Writing a simple function that, given an array of uppercase strings, returns an array with the same strings in lowercase
Imperative approach
const toLowerCase = input => { const output = []; for (let i = 0; i < input.length; i++) { output.push(input[i].toLowerCase()); } return output; };
toLowerCase(['FOO', 'BAR']) // ['foo', 'bar']
Declarative approach
const toLowerCase = input => input.map(value => value.toLowerCase());
Exercise 2
Show a map with a marker
Imperative approach
const map = new google.maps.Map(document.getElementById('map'), { zoom: 4, center: myLatLng }); const marker = new google.maps.Marker({ position: myLatLng, title: 'Hello World!' }); marker.setMap(map);
Declarative approach
<Gmaps zoom={4} center={myLatLng}> <Marker position={myLatLng} title="Hello world!" /> </Gmaps>
Component pattern
Make components as reusable as possible (Presentational component)
- View: This is a presentational component
- Model: This is a data representation, which in our case is the state that is built either in a stateful component or using so-called store and reducers
- Controller: This is a container component
- Responsible for application logic, including event handlers and services
- Should be lean and import logic from the respective files
Stateful component
Stateless (functional) component
Component composition
- Similar OOP – Inheritance, but not totally
- Instead of creating a new class and inheriting from the base class, we will create a new parent component that will use its child component to make itself more specific or more powerful
Presentational component
Decouples components from logic and makes them flexible
Container component
HOC
Enhance components with additional props or functionality, for instance, if you want to make the component expandable
HOC pattern is very similar to the decorator pattern in OOP
Styling pattern
In React Native, everything is relative by default. This means that if I nest View into another View that has marginTop: 40, this positioning will affect my nested View too
Flexible Box pattern
Animations
- You need a style attribute, its starting value, and its end value
- Animation is what you see when this value goes from start to end over time
- You can combine many attributes and possibly animate many components at the same time
Flux architecture
Flux is an architectural pattern for building React user interfaces
Store pattern
Redux
Navigation pattern
Functional programming pattern
First-class objects
Functions are first-class objects, which means that they can be assigned to variables and passed as parameters to other functions.
This allows us to introduce the concept of higher-order functions (HoFs).
HoFs are functions that take a function as a parameter, optionally some other parameters, and return a function. The returned function is usually enhanced with some special behaviors.
const add = (x, y) => x + y; const log = fn => (...args) => { console.log(...args); return fn(...args); }; const logAdd = log(add);
Purity
A function is pure when there are no side-effects, which means that the function does not change anything that is not local to the functions itself
Pure function
const add = (x, y) => x + y;
Impurity function
let x = 0; const add = y => (x = x + y);
Immutability
Instead of changing the value of a variable, creates a new variable with a new value and returns it.
This way of working with data is called immutability. An immutable value is a value that cannot be changed
This function doesn’t follow immutability
because if we call the same function twice, we get different results.
const add3 = arr => arr.push(3); const myArr = [1, 2]; add3(myArr); // [1, 2, 3] add3(myArr); // [1, 2, 3, 3]
This one does
because after we have run the function twice, myArr still has its original value
const add3 = arr => arr.concat(3); const myArr = [1, 2]; const result1 = add3(myArr); // [1, 2, 3] const result2 = add3(myArr); // [1, 2, 3]
Currying
Instead of writing the following code:
const add = (x, y) => x + y;
We define the function as follows:
const add = x => y => x + y;
And we use it in the following way:
const add1 = add(1); add1(2); // 3 add1(3); // 4
This is a pretty convenient way of writing functions because, since the first value is stored after the application of the first parameter, we can reuse the second function multiple times.
Composition
const add = (x, y) => x + y; const square = x => x * x;
const addAndSquare = (x, y) => square(add(x, y));
Following this paradigm, we end up with small, simple, testable
pure functions that can be composed together.
FP and user interfaces
We can think about a UI as a function to which is applied the state
of the application, as follows:
UI = f(state);
Leave a Reply