Code tips #5: React – How to avoid extra control property

In React many times we have components that have some slight variations and we want to control how these components will be rendered. For example, we have a mobile and a desktop version of a component. Usually React developers tend to add an extra property in the component based on which they control the version of the component that will be rendered, either through if or switch statements.

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import ProductCardSmall from './ProductCardLarge';
import ProductCardMedium from './ProductCardMedium';
import ProductCardLarge from './IPBadgeLarge';

export default class ProductCard extends Component {
  static propTypes = {
    cardType: PropTypes.string,
  };

  render() {
    const { cardType } = this.props;

    switch (cardType) {
      default:
      case 'small':
        return <ProductCardSmall {...this.props} />;
      case 'medium':
        return <ProductCardMedium {...this.props} />;
      case 'large':
        return <ProductCardLarge {...this.props} />;
    }
  }
}

And then use the component like:

<ProductCard cardType="medium" />

But there is a way to simplify the code by Continue reading Code tips #5: React – How to avoid extra control property

Code Tips #4: Let subclasses provide defaults

Inheritance is a powerful mechanism which allows us to share code and avoid duplication, but as Marvel’s comics teach us “With great power comes great responsibility”. Imagine a scenario where you have a superclass and some subclasses, the superclass provides some default values for the instances in case the parameter value is not passed.

class Vehicle{
  constructor(args = {}){
    this.speed = args.speed === undefined ? 100 : args.speed;
    this.color = args.color === undefined ? 'red' : args.color;
  }
}

The problem with this design is that Continue reading Code Tips #4: Let subclasses provide defaults

Code Tips #3: Remove argument-order dependency and provide defaults

Argument order in function signature is a common source of bugs and frustration. Imagine you have the following Vehicle class, its constructor accepts values to instantiate an object. Passing the values in the wrong order can easily lead to bugs that are not so easy to catch.

class Vehicle {
  constructor(speed, weight, power, color, brand){
    this.speed = speed;
    this.weight = weight;
    this.power = power;
    this.color = color;
    this.brand = brand;
  }
}

Continue reading Code Tips #3: Remove argument-order dependency and provide defaults

Code Tip #2: Isolate References to external classes

Imagine we have the following Vehicle class that has a dependency on the speed property of an Engine class.

class Engine {
  constructor(speed){
    this.speed = speed * 1.2;
  }
}

The Engine class accept a speed value and uses a factor to define the final speed. Its internals is not so important. Continue reading Code Tip #2: Isolate References to external classes

Code Tips #1: Hide Dependency to a Data Structure

Many times we encounter situations where our code depends on a complicated data structure or a data structure that has implicit semantics. For example, let’s say we create a chart and the data that we have to use is a response from a server (we can’t change the structure of the response). The response from the server looks like this:

[
 ["2018-12-02", 1000], 
 ["2018-11-02", 900], 
 ["2018-10-02", 200], 
 ["2018-09-02", 300]
]

This structure has an implicit meaning, it is an array of arrays, each of which has two values, the first represents a date and the second one a value. The naive approach is to Continue reading Code Tips #1: Hide Dependency to a Data Structure

Implementing backpressure for smoother user experience in low-end devices

If you are building applications that consume real-time data you may have faced a situation where the component or service that consumes the data cannot keep up with the volume or speed of the produced data. The “producer” module of the system is emitting data faster than the “consumer” module of the system can process.

The consumer tries to keep up processing the data by increasing the amount of the system resources it is using (CPU, memory), that can be fair in Continue reading Implementing backpressure for smoother user experience in low-end devices