React Native – Design Patterns

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);

Be the first to comment

Leave a Reply

Your email address will not be published.


*