Easy React

Rahul Biswas
7 min readMay 5, 2020

--

Day 2 of React Learning — Milestone 2 (Week 2)

Welcome to the 2nd day of React learning. Today we will discuss shortly about some of the easiest and fun topics of React such as JSX, Default props in React, How to use prop-types in React, Error handling in React, Unit Testing, Optimizing the Performance of React App. Let’s dive into it.

1. Dot Notation for JSX Type

A React component can be referred to using dot-notation from within JSX. This is convenient if we have a single module that exports many React components.

Example:

MyComponents.DatePicker is a component, we can use it directly from JSX

2. JS Expressions as Props

For example,

<MyComponent foo={1 + 2 + 3 + 4} />

We can pass any JavaScript expression as a prop, by surrounding it with {}

For MyComponent, the value of props.foo will be 10 because the expression 1 + 2 + 3 + 4 gets evaluated.

if statements and for loops are not expressions in JavaScript, so they can’t be used in JSX directly. Instead, we can put these in the surrounding code.

Example:

3. defaultProps

It is a property on the component class itself, to set the default props for the class. This is used for undefined props, but not for null props. E

Example:

If props.color is not provided, it will be set by default to ‘blue’:

If props.color is set to null, it will remain null:

4. prop-types: validating React component props

Props are a very important mechanism for passing read-only attributes to React components. These attributes are usually required to be of certain types or forms for them to be used properly in the component.

If a prop is passed to a component in a type or form that isn’t expected, the component may not behave as we intended. Thus, a great way of improving React components is props validation.

Installation:

npm install — save prop-types

Import to the app:

import PropTypes from ‘prop-types’;

How to use prop-types in a React class:

class MyComponent extends React.Component {
render() {
// … do things with the props
}
}

MyComponent.propTypes = {
// prop for specific JS primitive. By default, these are all optional.
optionalArray: PropTypes.array,
optionalBool: PropTypes.bool,
optionalFunc: PropTypes.func,
optionalNumber: PropTypes.number,
optionalObject: PropTypes.object,
optionalString: PropTypes.string,
optionalSymbol: PropTypes.symbol,

// for numbers, strings, elements or an array for more info
optionalNode: PropTypes.node,

// for React element (i.e. <MyComponent />)
optionalElement: PropTypes.element,

// for React element type (ie. MyComponent).
optionalElementType: PropTypes.elementType,

// using instanceof operator, a prop can be declared as an instance of a class.
optionalMessage: PropTypes.instanceOf(Message),

// An object taking on a particular shape
optionalObjectWithShape: PropTypes.shape({
optionalProperty: PropTypes.string,
requiredProperty: PropTypes.number.isRequired
}),

// An object with warnings on extra properties
optionalObjectWithStrictShape: PropTypes.exact({
optionalProperty: PropTypes.string,
requiredProperty: PropTypes.number.isRequired
}),

requiredFunc: PropTypes.func.isRequired,

// A value of any data type
requiredAny: PropTypes.any.isRequired,

5. Error Boundaries

Imagine, how fun this would be to detect and appear the internal or behind the scene’s error messages very easily using the code style we are working on? React provides us a powerful technique to do that, which is called ‘Error Boundaries’.

Error boundaries are React components that catch JavaScript errors anywhere in their child component tree, log those errors, and display a fallback UI instead of the component tree that crashed. Error boundaries catch errors during rendering, in lifecycle methods, and in constructors of the whole tree below them.

Example:

We can use it as a regular component

6. Component Stack Traces

During DOM rendering, React prints all error messages that it catches. This is an extremely salient feature for debugging errors for the development phase.
We can see where exactly in the component tree the failure has happened.

Example:

Before clicking the numbers

After clicking any one number of the 1st segment’s more than 5 times, the count stops completely for both numbers and we get this error

After clicking the 1st segment (more than 5 times)

and for the 2nd segment when we clicked the 1st number more than 5 times, the error only occurs for the 1st number, which means the 2nd number remains unchanged.

7. Unit Testing

Unit Testing is a type of software testing where individual units or components of a software are tested. The purpose is to validate that each unit of the software code performs as expected. Unit Testing is done during the development (coding phase) of an application by the developers. Unit Tests isolate a section of code and verify its correctness. A unit may be an individual function, method, procedure, module, or object.

How to perform unit tests?
Here we’ve considered a very simple function for the testing:

int CombineNumbers(int a, int b) {
return a+b;
}

performing the unit test:

void TestCombineNumbers() {
Assert.IsEqual(CombineNumbers(5, 10), 15); // Assert is an object that is part of the test framework
Assert.IsEqual(CombineNumbers(1000, -100), 900);
}

When we run the tests, we will be informed that these tests have passed. Now that we’ve built and run the tests, we know that this particular function, or unit, will perform as we expect.

Now if another developer comes along and changes the CombineNumbers() function for performance, or some other reason:

int CombineNumbers(int a, int b) {
return a * b;
}

When the developer runs the tests that we have created for this very simple function, they will see that the first Assert fails, and they now know that the build is broken.

8. How to effectively Unit Test React Apps

No matter what framework we use, the following tips will help us to write better, more testable, more readable, more composable UI components:

  • Favor pure components for UI code: given the same props, always render the same component. If you need state from the app, you can wrap those pure components with a container component that manages state and side-effects.
  • Isolate application logic/business rules in pure reducer functions.
  • Isolate side effects using container components.

9. Speed Up React: Profiling Components

One of the efficient techniques in React is (and why it is so popular) that it optimizes costly DOM operations as much as possible. React ignores unchanged DOM UI, and saves a lot of time and memory. We can visually utilize the optimization and detect what’s going behind the scenes of a React app with the help of some dev tools.

i) Chrome Performance Tab

Using React Developer Tools in the Chrome browser, we can visualize the optimization for the supported browsers in the following steps:

  1. Temporarily disable all Chrome extensions, including React DevTools.
  2. The application must run in the development mode.
  3. Open the Chrome DevTools Performance tab and press Record.
  4. Perform the actions you want to profile. Don’t record more than 20 seconds or Chrome might hang.
  5. Stop recording.
  6. React events will be grouped under the User Timing label.

ii) DevTools Profiler

React DevTools Profiler is a profiling capability that React DevTools supports for app optimization. If you have installed React DevTools, you will found the Profiler tab by enabling Developers Mode (‘ctrl+shift+i’ in windows) or right click → Inspect. Remember, it will only work in the React Devtool’s development mode (red react logo in the top right corner of the browser), not in the production mode.

10. shouldComponentUpdate In Action

React always ignores the rendering of unchanged UI DOM, which makes the app faster. We can explain it through a tree example:

Image credit: https://reactjs.org/docs/optimizing-performance.html#shouldcomponentupdate-in-action

In the image above, it is clear to see that -

i) sub-root C2 → shouldComponentUpdate returned false (green-colored)

Hence, the sub-tree of C2 will remain completely unchanged
a) C4 will be unchanged (no reconciliation needed, green-colored)
b) C5 will be unchanged (no reconciliation needed, green-colored)

ii) sub-root C3 → shouldComponentUpdate returned true (red-colored)

Here, the sub-tree of C3 can be partially affected or remain completely unchanged
a) C6 will change (reconciliation needed, red-colored)
b) C7 will be unchanged (no reconciliation needed, green-colored)
c) For C8 React have to render this component, but since the React elements it returned were equal to the previously rendered ones, it didn’t have to update the DOM

That’s all for today…Thanks for Reading. Happy Learning :)

--

--

Rahul Biswas

Love to work with Technologies, Web & obviously JavaScript.