YuWebdesign



React.js Interview Questions

By YuwebDesign


Foundations of React.js

  1. React JS is a front end JavaScript-based UI library for building web interfaces.
  2. It was developed by Facebook in 2011
  3. React allows developers to build interactive reusable UI components
  4. It has the support of a large, open source community

Fiber
is the new reconciliation engine
or reimplementation of core algorithm
in React v16.

The goal of React Fiber
is to increase its suitability for areas like
animation,
layout,
gestures,
ability to pause, abort, or reuse work
and assign priority to different types of updates;
and new concurrency primitives.

Its headline feature is incremental rendering:
the ability to split rendering work into chunks
and spread it out over multiple frames.

When you use React, at a single point in time
you can think of the render() function
as creating a tree of React elements.

On the next state or props update,
that render() function will return
a different tree of React elements.

React then needs to figure out
how to efficiently update the UI
to match the most recent tree.

The Diffing Algorithm

When diffing two trees, React first compares the two root elements. The behavior is different depending on the types of the root elements.

Elements Of Different Types

Whenever the root elements have different types,
React will tear down the old tree and build the new tree from scratch.

When tearing down a tree, old DOM nodes are destroyed.

Component instances receive componentWillUnmount().

When building up a new tree,
new DOM nodes are inserted into the DOM.

Component instances receive componentWillMount()
and then componentDidMount().
Any state associated with the old tree is lost.

Any components below the root will also get unmounted and have their state destroyed.

DOM Elements Of The Same Type

When comparing two React DOM elements of the same type,
React looks at the attributes of both,
keeps the same underlying DOM node,
and only updates the changed attributes.

<div className="before" title="stuff" />

vs.

<div className="after" title="stuff" />

By comparing these two elements,
React knows to only modify the className
on the underlying DOM node.

Component Elements Of The Same Type

When a component updates, the instance stays the same, so that state is maintained across renders. React updates the props of the underlying component instance to match the new element, and calls componentWillReceiveProps() and componentWillUpdate() on the underlying instance.

Next, the render() method is called and the diff algorithm recurses on the previous result and the new result.

Read more >>>

React JS
is a front end, open source JavaScript library used for building UIs.

React Native
is an open source, mobile framework
that allows developers to use React
for building mobile applications
on Windows, Android, and iOS.

React Native compiles to native app components
We can mimic the behavior of the native app in JavaScript
and get a platform-specific code as the output.

It is also possible to mix the native code with the JavaScript
if we need to optimize our application further.

React

The react package
contains
React.createElement(),
React.Component,
React.Children,
and other helpers related to elements and component classes.

You can think of these
as the isomorphic or universal helpers
that you need to build components.

ReactDOM

The react-dom package
contains ReactDOM.render(),
and in react-dom/server
we have server-side rendering support
with ReactDOMServer.renderToString()
and ReactDOMServer.renderToStaticMarkup().

React vs. ReactDOM

ReactDOM is the glue between React and the DOM.

Often, we will only use it for one single thing:
mounting with ReactDOM.

Another useful feature of ReactDOM
is ReactDOM.findDOMNode()
which we can use to gain direct access to a DOM element.

For everything else, there’s React.

We use React
to define and create our elements,
for lifecycle hooks, etc.
i.e. the guts of a React application

React Angular
MVC React is a library and has only the View layer Angular is a framework and has complete MVC functionality
SSR React handles rendering on the server side AngularJS renders only on the client side but Angular 2 and above renders on the server side
Syntax React uses JSX that looks like HTML in JS Angular follows the template approach for HTML,
which makes code shorter and easy to understand
Mobile React Native, which is a React type to build mobile applications are faster and more stable Ionic, Angular’s mobile native app is relatively less stable and slower
Data flow In React, data flows only in one way and hence debugging is eas In Angular, data flows both way i.e it has two-way data binding between children and parent and hence debugging is often difficult

You can use React.version to get the version.

const REACT_VERSION = React.version

ReactDOM.render(
  <div>{`React version: ${REACT_VERSION}`}</div>,
  document.getElementById('app')
)

  1. High efficiency and performance
    Increased application performance, flexibility and efficiency via the Virtual DOM model. It automatically calculates the changes needed to be made in DOM thus avoiding expensive DOM options and making regular updates whenever needed.
  2. Easier JavaScript writing
    Improved coding efficiency with JSX.
    Thanks to the JSX syntax which allows you to mix HTML with JavaScript, writing is much easier with React. React then turns those HTML bits into functions with its JSXTransformer.
    JSX makes it easy to read the code of the components.
  3. Modularity
    The ability to reuse components across multiple projects.

    It is easy to know how a component is rendered,
    you just need to look at the render function.

    It is also really easy to see the layout,
    or how components are plugged/combined with each other.

  4. A variety of developer tools
    through a variety of developer add-on tools provided by React’s open source community.

    E.g., the official browser extension lets to get the most out of React.js.
    It comes in quite handy, especially for debugging the app.
    It gives you a direct look into the virtual DOM as if you were browsing a regular DOM tree in the elements panel.

  5. Flexibility and extensibility
    You can use React with any framework you wish
    as it is only a view layer.
  6. It is easy to know how a component is rendered,
    you just need to look at the render function.
  7. Great for SEO
    Most of the JavaScript frameworks aren’t particularly search engine friendly,
    but that is not the case with React.
    Thanks to its unique virtual DOM that is rendered to the browser as a regular page,
    the search engines will not encounter the same issues as with reading other JavaScript-heavy apps.
  8. You can render React on the server-side.
    This improves SEO and performance.
  9. UI Test Cases
    It is very easy to write UI test cases thanks to the virtual DOM in JavaScript.

One of the main reasons this question is of interest to an interviewer
is because it gives a sense of how you might explain
the importance of using React to a non-technical client or stakeholder.

React is easy to learn and start with, but allows plenty of room for growth over time (showing your willingness to learn new things and expand your knowledge as you go).

There are so many job opportunities for React developers
(showing you keep on top of the industry and are able to adapt as needed).

  1. React JS is a JavaScript library
    and not a full-blown framework,
    meaning it might not be full service enough for some project.
  2. Integration with traditional MVC framework requires major configurations
  3. React’s library is extremely large
    and can take additional time and experience (past the initial learning phase)
    to really understand
  4. JSX adds a new coding dimension for developers who haven’t used before
    (though it does have a gentle learning curve due to its similarity to HTML)

  1. Renaming Unsafe Lifecycle Methods
  2. Deprecating javascript: URLs
  3. Async act() for Testing
  4. Performance Measurements with <React.Profiler>

The dangerouslySetInnerHTML attribute
is React’s replacement
for using innerHTML in the browser DOM.

Just like innerHTML,
it is risky to use this attribute
considering cross-site scripting (XSS) attacks.

You just need to pass a __htmlobject as key
and HTML text as value.

function createMarkup() {
  return { __html: 'First · Second' }
}

function MyComponent() {
  return <div dangerouslySetInnerHTML={createMarkup()} />
}

JSX and Conditional Render

JSX is a key feature of React.

You describe Elements with JSX
JSX is an alternative syntax for React.createElement that doesn’t introduce any new functionality, but makes the code easier to read.
React developers came up with an unorthodox solution: a new syntax to describe user interfaces inside JavaScript files.
Instead of writing React.createElement by hand, you write the element description in a syntax that’s almost identical to HTML, called JSX.
Then, before the application runs, you process your source with a tool called Babel to replace JSX with React.createElement.

JSX vs separate template files
When compared to templates, the advantage to this approach is
that there are fewer special rules to learn than with a separate template language,
and error messages tend to be easier to interpret.
The trade-off is that you need a build step to prepare your code for production.

JSX
is an XML/HTML-like syntax extending JavaScript
that let’s developers write HTML style code inside of JavaScript.

JSX produces React “elements”.

JSX lives within the same file with JavaScript code and can be:
written inside of if statements and for loops,
assigned it to variables,
accepted it as arguments,
and returned it from functions.

After compilation,
JSX expressions will be automatically transformed
into regular JavaScript code.

This transformation of JSX into standard JavaScript objects
that a JavaScript engine will parse
is done by preprocessors (i.e., transpilers like Babel).

You can embed any JavaScript expression in JSX
by wrapping it in curly braces.

Developers do NOT need to use JSX to build websites or applications with React,
but it can be a helpful tool for reducing overall code complexity
(and Facebook encourages using it in their official React documentation).

Browsers cannot read JSX.

There is always a need to compile the files
that contain JSX Code.

This is usually done with the help of JSX compiler
which performs its task
prior to file entering the browser.

After compilation,
JSX expressions will be automatically transformed
into regular JavaScript code.

This transformation of JSX into standard JavaScript objects
that a JavaScript engine will parse
is done by preprocessors (i.e., transpilers like Babel).

It is possible.
The process is quite similar to that of nesting the HTML elements.

In such a situation, enclosing the multi-line JSX expression is an option.

Avoid multi-line expressions
to perform the task reliably
and for getting the results as expected.

If you try to render a <label> element
bound to a text input
using the standard “for” attribute,
rendered HTML will be missing that attribute
and awarning will be printed to the console.

<label for={'user'}>{'User'}</label>
<input type={'text'} id={'user'} />

Since “for” is a reserved keyword in JavaScript,
use “htmlFor” instead.

<label htmlFor={'user'}>{'User'}</label>
<input type={'text'} id={'user'} />

React JSX doesn’t support variable interpolation
inside an attribute value.

The below representation won’t work:

<img className='image' src='images/{this.props.image}' />

But you can put any JS expression
inside curly braces
as the entire attribute value.

<img className='image' src={'images/' + this.props.image} />

Using template strings will also work:

<img className='image' src={`images/${this.props.image}`} />

In some cases you want to render different components
depending on the state.

JSX does not render false or undefined,
so you can use conditional short-circuiting
to render a given part of your component
only if a certain condition is true.

With &&
const MyComponent = ({ name, address }) => (
  <div>
    <h2>{name}</h2>
    {address &&
      <p>{address}</p>
    }
  </div>
)
With ternary operator

If you need an if-else condition then use ternary operator.

const MyComponent = ({ name, address }) => (
  <div>
    <h2>{name}</h2>
    {address
      ? <p>{address}</p>
      : <p>{'Address is not available'}</p>
    }
  </div>
)

In a class based React version >=16.2 there are a few possible options:

 
render() {
  return false
}
render() {
  return null
}
render() {
  return []
}
render() {
  return <React.Fragment7gt;</React.Fragment>
}
render() {
  return <></>
}

Returning undefined won’t work.

You can simply use Array.prototype.map with ES6 arrow function syntax.
Array of objects is mapped into an array of components:

<tbody>
  {items.map(item => <SomeComponent key={item.id} name={item.name} />)}
</tbody>

You can’t iterate using for loop.

This is because JSX tags are transpiled into function calls,
and you can’t use statements inside expressions.

<tbody>
  for (let i = 0; i < items.length; i++) {
    <SomeComponent key={items[i].id} name={items[i].name} />
  }
</tbody>

React Diffing Algorithm for Recursing On Children

By default, when recursing on the children of a DOM node,
React just iterates
over both (old and new) lists of children at the same time
and generates a mutation whenever there’s a difference.

For example, when adding an element at the end of the children,
converting between these two trees works well:

<ul>
  <li>first</li>
  <li>second</li>
</ul>

vs.

<ul>
  <li>first</li>
  <li>second</li>
  <li>third</li>
</ul>

React will match the two <li>first</li> trees,
match the two <li>second</li> trees,
and then insert the <li>third</li> tree.

If you implement it naively,
inserting an element at the beginning
has worse performance.

For example, converting between these two trees works poorly:

<ul>
  <li>Duke</li>
  <li>Villanova</li>
</ul>

vs.

<ul>
  <li>Connecticut</li>
  <li>Duke</li>
  <li>Villanova</li>
</ul>

React will mutate every child
instead of realizing it can keep the <li>Duke</li> and <li>Villanova</li> subtrees intact.

This inefficiency can be a problem.

Keys

In order to solve this issue, React supports a key attribute.
Keys help React identify which items have changed, are added, or are removed.

Keys should be given to the elements inside the array
to give the elements a stable identity.

When children have keys,
React uses the key to match children in the original tree
with children in the subsequent tree.

The best way to pick a key
is to use a string that uniquely identifies
a list item among its siblings.

Most often you would use IDs from your data as keys.

When you don’t have stable IDs for rendered items,
you can add a new ID property to your model
or hash some parts of the content to generate a key.

The key only has to be unique among its siblings, not globally unique.

As a last resort, you can pass an item’s index in the array as a key.
This can work well if the items are never reordered, but reorders will be slow.

Read more >>>

Keys should be stable, predictable, and unique
so that React can keep track of elements.

If each element’s key is be based on ordering,
rather than tied to the data that is being represented,
this limits the optimizations that React can do.

{todos.map((todo, index) =>
  <Todo
    {...todo}
    key={index}
  />
)}

If you use element data for unique key,
assuming todo.id is unique to this list and stable,
React would be able to reorder elements
without needing to reevaluate them as much.

{todos.map((todo) =>
  <Todo {...todo}
    key={todo.id} />
)}

As a last resort, you can pass an item’s index in the array as a key.
This can work well if the items are never reordered,
but reorders will be slow.

Reorders can also cause issues with component state
when indexes are used as keys.
Component instances are updated and reused based on their key.

If the key is an index,
moving an item changes it.
As a result, component state for things like uncontrolled inputs
can get mixed up and updated in unexpected ways.

Read more >>>

If you want to use async/await in React,
you will need Babel
and transform-async-to-generator plugin.

React Native ships with Babel and a set of transforms.

JSX and CSS

“Class” is a reserved word in React.

If you use the word “Class”
the JSX will be translated to JavaScript immediately.

However, you can use the word “ClassName”.

The style attribute accepts a JavaScript object
with camelCased properties rather than a CSS string.

This is consistent with the DOM style JavaScript property,
is more efficient,
and prevents XSS security holes.

Style keys are camelCased
in order to be consistent
with accessing the properties on DOM nodes in JavaScript
(e.g. node.style.backgroundImage).

const divStyle = {
  color: 'blue',
  backgroundImage: 'url(' + imgUrl + ')'
};

function HelloWorldComponent() {
  return <div style={divStyle}>Hello World!</div>
}

You can use spread operator in regular React:

 <button style={{...styles.panel.button, ...styles.panel.submitButton}}>
   {'Submit'}
 </button>

If you’re using React Native then you can use the array notation:

 <button style={[styles.panel.button, styles.panel.submitButton]}>
  {'Submit'}
 </button>

React does not apply vendor prefixes automatically.
You need to add vendor prefixes manually.

<div style={{
  transform: 'rotate(90deg)',
  WebkitTransform: 'rotate(90deg)', // note the capital 'W' here
  msTransform: 'rotate(90deg)' // 'ms' is the only lowercase vendor prefix
}} />

You shouldn’t use curly braces inside quotes
because it is going to be evaluated as a string:

<div className="btn-panel {this.props.visible ? 'show' : 'hidden'}">

Instead you need to move curly braces outside
(don’t forget to include spaces between class names):

<div className={'btn-panel ' + (this.props.visible ? 'show' : 'hidden')}>

Template strings will also work:

<div className={`btn-panel ${this.props.visible ? 'show' : 'hidden'}`}>

Virtual DOM

Document Object Model (DOM)
When web browsers render HTML documents
and turn them into a website or application on a screen,
they create a representational tree of how the site or app is arranged
called a Document Object Model (DOM).

The Document Object Model or DOM
defines an interface that allows languages such as JavaScript
to access and manipulate an HTML document.

Elements are represented by nodes in a tree
and the interface allows us to manipulate them.

This interface, however, comes with a cost
and a large number of very frequent DOM operations
will slow down the page.

Without React,
your website or app will use HTML to update its DOM
in order to make things “change” on screen
without users needing to manually refresh a page.

React JS takes a different approach
by creating a Virtual DOM —
a copy of the site’s “actual” DOM.

When state changes in a component
React firstly runs a “diffing” algorithm,
which identifies what has changed in the Virtual DOM
to determine what parts of the actual DOM need to change
(based on user actions).

The second step is reconciliation,
React then takes the changes/results of diff from the Virtual DOM
and selectively updates the actual DOM
(versus reloading the entire thing).

Over time, this leads to significant performance improvements
for the website or application.

What is change detection?

Change detection
is the mechanism designed to track changes in an application state
and render the updated state on the screen.

It ensures that the user interface always stays in sync
with the internal state of the program.

We can infer from this definition
that change detection has two main parts:
tracking changes and rendering.

Rendering
Let’s take a look at rendering first.
In any application, the process of rendering
takes the internal state of the program
and projects it into something we can see on the screen.

In web development, we take data structures like objects and arrays
and end up with a DOM representation of that data
in the form of images, buttons and other visual elements.

Although the implementation of rendering logic may not always be trivial,
it’s still pretty straightforward.

Things start to get a lot more sophisticated
when we mix in data that changes over time.

Web applications today are interactive.
Which means that the application state can change any time
as a result of a user interaction.

There can be other reasons as well.
Something else happens in the world
that updates the server data.
Then our client fetches the update.

Checking
As our state changes, we need to detect that and reflect the change.

Frameworks take care of synchronization
between the internal state of the application
and the user interfaces for us.

But not only do they take some weight off our shoulders,
they do the state tracking and DOM updates very efficiently.

The idea of using expressions as values for DOM element properties
is the same in both Angular and React,
the underlying mechanisms are completely different.

Dirty Checking

The term “dirty checking” comes from Angular.

When the compiler analyzes the template,
it identifies properties of a component
that are associated with DOM elements.

For each such association,
the compiler creates a binding
in the form of instructions.

A binding is the core part of change detection in Angular.
It defines an association between a component’s property
and the DOM element property.

Once bindings are created,
Angular no longer works with the template.

The change detection mechanism
executes instructions
that process bindings.

The job of these instructions is to check
if the value of an expression with a component property has changed
and perform DOM updates if necessary.

E.g., Angular created the binding for the className
and the current values of the binding are as follows:

{ dirty: false, value: 'outline' }

Angular runs change detection and processes the instructions.
The first function takes the result of the evaluated expression
and uses it to compare to the previous value remembered by the binding.

This is where the name “dirty checking” comes from.
If the value has changed, it updates the current value
and marks this binding as dirty.

{ dirty: true, value: 'solid' }

The second instruction checks if the binding is dirty
and if so, uses the new value to update the DOM.

Processing bindings that perform dirty checks
and update the relevant parts of the DOM
are the core operations of change detection in Angular.

Virtual DOM

The core part of the change detection mechanism in React
is Virtual DOM comparisons.

  1. All React components implement the render method
    that returns a JSX template.
  2. A template is compiled
    into a bunch of React.createElement function calls.
  3. Each сall of the React.createElement function
    creates a data structure known as a Virtual DOM node.

    Nothing fancy, it’s just a plain JavaScript object
    that describes an HTML element, its properties and children.

  4. And when you have multiple calls to the function,
    collectively, they create a Virtual DOM tree.

    So, eventually the render method returns a Virtual DOM tree.

  5. Expressions with a component property
    are evaluated at the time of the render function call.
    The Virtual DOM node properties contain the results
    of the evaluated expressions.
  6. In React we always initialize the process of change detection manually.
    And we do it by calling the setState function.

    There’s no way to trigger change detection automatically in React.
    Every change detection cycle starts with the call to the setState function.

  7. After change detection,
    React executes the render function
    that returns a new version of Virtual DOM tree.
    E.g., setting a value on the state
    will signal to a listener
    that some state has changed.
  8. It’s very important to understand
    that the render function is called
    during each change detection cycle.

    This means that every time the function is called,
    it can return a completely different Virtual DOM tree.

  9. React runs a diffing algorithm on the two Virtual DOMs
    to get the set of changes between them.
    Once the difference is found,
    the algorithm produces a patch
    to update the corresponding DOM nodes.

Virtual-DOM is more efficient than Dirty checking
This is ignificantly faster than the Dirty Checking
because we don’t have to poll the data at a regular interval
and check all of the values in the data structure recursively.

Virtual DOM is more efficient than the Dirty checking
simply because it prevents all the unnecessary re-renders.
Re-rendering only occurs when the state changes.

All React components must have a render() method.

Whenever something the your app is changed
by calling the setState({}) method on ‘any’ component
the render() method is being called on all components,
starting from the topmost component.

Sounds like a terrible overhead,
how can this be so fast at all?

The render() method does not render anything into the real DOM.
Instead its ‘rendering’ into a virtual DOM
and then diffing it against the previous virtual DOM.

And only the difference
between before render() and after render()
is used to patch the real DOM.

Very few real DOM calls.

We can help React to save some render() calls
by adding the methods

  1. componentWillReceiveProps({})
    to check if the current component can use the given property
  2. shouldComponentUpdate({})
    to check if the current component will update either on state or property change.

Shadow DOM vs Virtual DOM

The Shadow DOM
is a browser technology designed primarily
for scoping variables and CSS in web components.

The Virtual DOM
is a concept implemented by libraries in JavaScript
on top of browser APIs.

Type Checking

Flow
is a static analysis tool (static checker)
which uses a superset of the language,
allowing you to add type annotations
to all of your code
and catch an entire class of bugs
at compile time.

PropTypes
is a basic type checker (runtime checker)
which has been patched onto React.

It can’t check anything other
than the types of the props
being passed to a given component.

If you want more flexible typechecking
for your entire project
Flow and TypeScript are appropriate choices.

TypeScript
is a free and open-source programming language
developed and maintained by Microsoft.

It is a strongly typed superset of JavaScript.

TypeScript is based on the ES6 version of JavaScript
with some additional features.

TypeScript is not directly run on the browser.

Transpiling
the process by which TypeScript code
is converted into JavaScript code.

We need TypeScript because:
  1. Object-Oriented language
    OOPs features such as classes, interfaces, inheritance, generics, etc.
    E.g., it supports reusability by using the inheritance.
  2. Full-stack
    In TypeScript, we can write code for both client-side as well as server-side development.
  3. Error-checking at compilation time
    It will compile the code,
    and if any error found,
    it highlights the errors before the script is run.
  4. TypeScript supports Static and Strong typing,
    and type checking gives us autocompletion.
  5. JavaScript is TypeScript

    Code written in JavaScript with valid .js extension
    can be converted to TypeScript
    by changing the extension from .js to .ts
    and compiled with other TypeScript files.

    TypeScript can be used to manipulate the DOM
    for adding or removing elements
    similar to JavaScript.

    TypeScript supports all JavaScript libraries
    because it is the superset of JavaScript.

    TypeScript supports the latest JavaScript features including ES6.

  6. TypeScript supports Modules
    and Optional Parameters (ability to emulate overloading)
  7. TypeScript is portable
    because it can be executed on any browsers, devices, or any operating systems.

    It can be run in any environment where JavaScript runs on.

    It is not specific to any virtual-machine for execution.

JavaScript (ES5) Typescript
developed by Netscape in 1995 developed by Anders Hejlsberg in 2012
source file is in “.js” extension source file is in “.ts” extension
doesn’t support ES6 supports ES6
doesn’t support strong or static typing supports strong or static typing feature
scripting language supports OOPs concepts
like classes, interfaces, inheritance, generics, etc.
doesn’t support generics supports generics
number and string are the objects number and string are the interface
doesn’t support modules support for modules
no optional parameter feature has optional parameter feature
interpreted language
(errors found at runtime)
compiles the code (errors found during the development time)
provides the error-checking feature at compilation time.
It will compile the code,
and if any error found,
it will be highlighted before the script is run.
  1. TypeScript takes a long time to compile the code.
  2. TypeScript does not support abstract classes.
  3. If we run the TypeScript application in the browser,
    a compilation step is required to transform TypeScript into JavaScript.

React Ecosystem

The react-dom package
provides DOM-specific methods
that can be used at the top level of your app
and as an escape hatch
to get outside of the React model
if you need to.

  1. render()
  2. hydrate()
  3. unmountComponentAtNode()
  4. findDOMNode()
  5. createPortal()

Most of your components should not need to use this module.

create-react-app
is the official CLI (Command Line Interface) for React
to create React apps with no build configuration.

We don’t need to install or configure tools like Webpack or Babel.
They are preconfigured and hidden
so that we can focus on the code.

We can install easily just like any other node modules.
Then it is just one command to start the React project.

Until you eject you are unable to configure webpack or babel presets.

Manual import from core-js

Create a file called (something like) polyfills.js
and import it into root index.js file.

Run npm install core-js or yarn add core-js
and import your specific required features.

import 'core-js/fn/array/find'
import 'core-js/fn/array/includes'
import 'core-js/fn/number/is-nan'
Using Polyfill service

Use the polyfill.io CDN
to retrieve custom, browser-specific polyfills
by adding this line to index.html:

<script src='https://cdn.polyfill.io/v2/polyfill.min.js?features=default,Array.prototype.includes'></script>

In the above script we had to explicitly request
the Array.prototype.includes feature
as it is not included in the default feature set.

Create a file called .env in the project root
and write the import path:

NODE_PATH=src/app

After that restart the development server.
Now you should be able to import anything
inside src/app without relative paths.

Debugging as a crucial part of the development process.

  1. Linters (eslint, jslint)
  2. Debuggers (React and Redux Developer Tools)

To tell React to build in Production mode we will use Webpack.

Webpack’s DefinePlugin method lets us to set NODE_ENV to production.

This will strip out things like propType validation and extra warnings/additional notices.

It is a good practice to minify the code.
React utilizes Uglify’s dead-code elimination
to strip out development only code and comments.
This will drastically reduce the size of your bundle/package.

You just need to use HTTPS=true configuration.

You can edit your package.json scripts section:

"scripts": {
  "start": "set HTTPS=true && react-scripts start"
}

Or just run

set HTTPS=true && npm start

Since the protocol change does not necessarily affect the UI change,
except maybe for a warning message about certificates,
there are not many changes.

All you need to do
is provide the new URL
and make sure you handle the security-related pop-ups.

The React Intl library
makes internalization in React straightforward,
with off-the-shelf components
and an API that can handle everything
from formatting strings, dates, and numbers,
to pluralization.

React Intl is part of FormatJS
which provides bindings to React
via its components and API.

Create a Polymer element:

<link rel='import' ****='../../bower_components/polymer/polymer.html' />
Polymer({
  is: 'calender-element',
  ready: function() {
    this.textContent = 'I am a calender'
  }
})

Create the Polymer component HTML tag by importing it in a HTML document, e.g. import it in the index.html of your React application:

<link rel='import' ****='./src/polymer-components/calender-element.html'>

Use that element in the JSX file:

import React from 'react'
class MyComponent extends React.Component {
  render() {
    return (
      <calender-element />
    )
  }
}
export default MyComponent

Events

Events
are reactions (hence the library name)
that are triggered by specific user actions
like clicking on a UI button,
hovering a mouse over a UI object,
using keyboard commands with the UI, etc.

Handling events in React elements has some syntactic differences:

  1. React event handlers are named using camelCase, rather than lowercase (HTML).
  2. With JSX you pass a function as the event handler, rather than a string.
  3. In HTML you can return false to prevent default behavior, in React you must call preventDefault() explicitly.

React normalizes events
so that they have consistent properties
across different browsers.

SyntheticEvent
is a cross-browser wrapper
around the browser’s native event.

It’s API is same as the browser’s native event,
including stopPropagation() and preventDefault(),
except the events work identically across all browsers.

If you find that you need the underlying browser event for some reason,
simply use the nativeEvent attribute to get it.

SyntheticEvent attributes

Every SyntheticEvent object has the following attributes:

boolean bubbles
boolean cancelable
DOMEventTarget currentTarget
boolean defaultPrevented
number eventPhase
boolean isTrusted
DOMEvent nativeEvent
void preventDefault()
boolean isDefaultPrevented()
void stopPropagation()
boolean isPropagationStopped()
DOMEventTarget target
number timeStamp
string type
e.stopPropagation() or e.preventDefault()

As of v0.14, returning false from an event handler
will no longer stop event propagation.
Instead, e.stopPropagation() or e.preventDefault()
should be triggered manually, as appropriate

The SyntheticEvent is pooled.
This means that
the SyntheticEvent object will be reused
and all properties will be nullified
after the event callback has been invoked.

This is for performance reasons.
That is why you cannot access the event in an asynchronous way.

event.persist()
If you want to access the event properties in an asynchronous way,
you should call event.persist() on the event,
which will remove the synthetic event from the pool
and allow references to the event
to be retained by user code.

function onClick(event) {
  console.log(event); // => nullified object.
  console.log(event.type); // => "click"
  const eventType = event.type; // => "click"

  setTimeout(function() {
    console.log(event.type); // => null
    console.log(eventType); // => "click"
  }, 0);

  // Won't work. this.state.clickEvent will only contain null values.
  this.setState({clickEvent: event});

  // You can still export event properties.
  this.setState({eventType: event.type});
}

React normalizes events
so that they have consistent properties
across different browsers.

The event handlers below
are triggered by an event
in the bubbling phase.

To register an event handler for the capture phase,
append Capture to the event name;
e.g., instead of using onClick, you would use onClickCapture
to handle the click event in the capture phase.

  1. Clipboard Events
  2. Composition Events
  3. Keyboard Events
  4. Focus Events
  5. Form Events
  6. Mouse Events
  7. Pointer Events
  8. Selection Events
  9. Touch Events
  10. UI Events
  11. Wheel Events
  12. Media Events
  13. Image Events
  14. Animation Events
  15. Transition Events
  16. Other Events

You can use an arrow function to wrap around an event handler and pass parameters:

<button onClick={() => this.handleClick(id)} />

This is an equivalent to calling .bind:

<button onClick={this.handleClick.bind(this, id)} />

Apart from these two approaches, you can also pass arguments to a function which is defined as array function

<button onClick={this.handleClick(id)} />
handleClick = (id) => () => {
    console.log("Hello, your ticket number is", id)
};

This can be done in two steps:

Create ref in render method

use the ref prop
to acquire a reference to the underlying HTMLInputElement object
through a callback,
store the reference as a class property.

<input ref={input => this.inputElement = input} />

Apply click event in your event handler

use the previously stored reference
to trigger a click
from your event handlers
using the HTMLElement.click method.

this.inputElement.click()

Refs

Refs are probably the most misunderstood and misused part of React.
All too often, developers are wrongly using refs to manipulate the DOM directly.

Refs as a reference to a DOM

Refs are used to get reference to a DOM node (element)
or an instance of a component in React.

They should be avoided in most cases,
e.g. good examples of when not to use refs are
trying to set a form value inputRef.current.value = ‘blablabla';
or dynamically adding and removing HTML elements (appendChild, removeChild, etc.)
The most powerful concept of React is a virtual DOM,
accessing DOM directly violates this concept.

However, refs can be useful when you need a direct access
to the DOM element or an instance of a component.

Good examples of when to use refs are
for managing focus/text selection,
triggering imperative animations,
or integrating with third-party DOM libraries.

Refs as a storage that is persisted across component renders

What makes refs so powerful is the fact that they are persisted between renders.
which makes them useful for any form of storage that is persisted
across component renders.

I like to think of refs very similarly to state, since they persist between renders,
but refs do not cause a component to re-render when changed.

Refs are just an object with .current property for storing a value that persists between renders.

Count the number of times a component re-renders

Wrong way to do so will be with state

function State() {
  const [formValue, setFormValue] = useState('');
  const [rerenderCount, setRerenderCount] = useState(0);

   useEffect(() => {
       setRerenderCount(prevCount => prevCount + 1);
    });

    return (
	<>
		<p>RenderCount: {rerenderCount}</p>
		<p>Form Value: {formValue}</p>
        <input value={formValue} onChange={e => setFormValue(e.target.value)}/>
	</>
	);
}

Right way to do so will be with refs

function Refs() {
 const [formValue, setFormValue] = useState('');
 const rerenderCount = useRef(0);

   useEffect(() => {
       rerenderCount.current = rerenderCount.current + 1;
    });

    return (
	<>
		<p>RenderCount: {rerenderCount}</p>
		<p>Form Value: {formValue}</p>
        <input value={formValue} onChange={e => setFormValue(e.target.value)}/>
	</>
	);
}

Both will correctly display the number of times a component has been re-rendered,
but in the state example the component will infinitely re-render itself
since setting the state causes the component to re-render.

The ref example on the other hand will only render once
since setting the value of a ref does not cause any re-renders.

Storing the previous value of a state variable
function Component() {
    const [inputValue, setInputValue] = useState('123456789')
    const previousName = useRef(null)

    useEffect(() => {
        previousName.current = inputValue;
    }, [inputValue])

  return (
    <>
		  <input value={inputValue} onChange={e => setInputValue(e.target.value)}/>
		  <p>Previous state: {previousName.current}</p>
		  <p>Current state: {inputValue}</p>
    </>
  )
}

Read more >>>

Callback refs vs. inline ref callbacks and string refs

You should avoid using string refs and inline ref callbacks.
Callback refs are advised by React.

String Refs are legacy

In an older version of React ref attribute is a string,
like ref={‘textInput’},
and the DOM node is accessed as this.refs.textInput.

We advise against it because string refs have below issues,
and are considered legacy.
String refs were removed in React v16.

They force React to keep track of currently executing component.
This is problematic because it makes react module stateful,
and thus causes weird errors
when react module is duplicated in the bundle.

They are not composable —
if a library puts a ref on the passed child,
the user can’t put another ref on it. Callback refs are perfectly composable.

They don’t work with static analysis like Flow.
Flow can’t guess the magic that framework does
to make the string ref appear on this.refs,
as well as its type (which could be different).

Callback Refs

Callback refs are friendlier to static analysis.
It doesn’t work as most people would expect
with the “render callback” pattern (e.g. )

class MyComponent extends Component {
  renderRow = (index) => {
    // This won't work. Ref will get attached to DataTable rather than MyComponent:
    return <input ref={'input-' + index} />;

    // This would work though! Callback refs are awesome.
    return <input ref={input => this['input-' + index] = input} />;
  }

  render() {
    return <DataTable data={this.props.data} renderRow={this.renderRow} />
  }
}

Ref forwarding
is a feature that lets some components take a ref they receive,
and pass it further down to a child.

const ButtonElement = React.forwardRef((props, ref) => (
  <button ref={ref} className="CustomButton">
    {props.children}
  </button>
));

// Create ref to the DOM button:
const ref = React.createRef();
<ButtonElement ref={ref}>{'Forward Ref'}</ButtonElement>

There are two approaches

This is a recently added approach. Refs are created using React.createRef() method and attached to React elements via the ref attribute. In order to use refs throughout the component, just assign the ref to the instance property within constructor.

class MyComponent extends React.Component {
  constructor(props) {
    super(props)
    this.myRef = React.createRef()
  }
  render() {
    return <div ref={this.myRef} />
  }
}

You can also use ref callbacks approach regardless of React version. For example, the search bar component’s input element accessed as follows,

class SearchBar extends Component {
   constructor(props) {
      super(props);
      this.txtSearch = null;
      this.state = { term: '' };
      this.setInputSearchRef = e => {
         this.txtSearch = e;
      }
   }
   onInputChange(event) {
      this.setState({ term: this.txtSearch.value });
   }
   render() {
      return (
         <input
            value={this.state.term}
            onChange={this.onInputChange.bind(this)}
            ref={this.setInputSearchRef} />
      );
   }
}

You can also use refs in function components using closures.

Note: You can also use inline ref callbacks
even though it is not a recommended approach

It is preferred to use callback refs over findDOMNode() API. Because findDOMNode() prevents certain improvements in React in the future.

The legacy approach of using findDOMNode:

class MyComponent extends Component {
  componentDidMount() {
    findDOMNode(this).scrollIntoView()
  }

  render() {
    return <div />
  }
}

The recommended approach is:

class MyComponent extends Component {
  componentDidMount() {
    this.node.scrollIntoView()
  }

  render() {
    return <div ref={node => this.node = node} />
  }
}

React Elements

React.createElement generates a description of the UI.
It can use either strings or a component. Strings describe single HTML elements.
Components combine multiple elements and describe a piece of UI as a function of data.
It is like a pipe that swallows data and outputs a representation of the UI:

 	Data --> Component --> Element

React.createElement accepts either a string that defines plain HTML elements, or a component.
By passing a component to React.createElement, you can combine components into more complex elements until you’ve built the whole interface.
You can replace React.createElement with JSX. Even though JSX looks like HTML, Babel eventually converts everything to React.createElement calls.
Babel assumes elements that start with a lowercase define regular HTML elements, and elements that start with a capital are based on components.

Question:

const element = (
  <h1 className="greeting">
    Hello, world!
  </h1>
);

Answer:

const element = React.createElement(
  'h1',
  {className: 'greeting'},
  'Hello, world!'
);

createElement
is what React uses to create React Elements.

cloneElement
is used to clone an element and pass it new props.

React.cloneElement

React.cloneElement
clones and returns a new React element
using the passed element as the starting point.

The resulting element
will have the original element’s props
with the new props merged in shallowly.
New children will replace existing children.
Key and ref from the original element will be preserved.

React.cloneElement only works
if our child is a single React element.

this.props.children

For almost everything this.props.children is the better solution.

Cloning is useful in some more advanced scenarios,
where a parent sends in an element
and the child component needs
to change some props on that element
or add things like ref for accessing the actual DOM element.

  1. Component
    A React Component is a template.
    A blueprint.
    A global definition.

    React component
    describes what you need to see on the screen.

    This can be either a function or a class (with a render function)
    which contains JSX
    that gets transpiled to a createElement invocation.

  2. Element
    A React Element is what gets returned from components.

    Element is the representation of the node in the DOM.

    It’s an object
    that virtually describes the DOM nodes
    that a component represents.

    With a function component,
    this element is the object
    that the function returns.

    With a class component,
    the element is the object
    that the component’s render function returns.

    React elements are not what we see in the browser.
    They are just objects in memory
    and we can’t change anything about them.

  3. Instance
    React internally creates, updates, and destroys instances
    to figure out the DOM elements tree
    that needs to be rendered to the browser.

    When working with class components,
    it’s common to refer to their browser-rendered DOM elements
    as component instances.

    You can render many instances of the same component.
    The instance is the “this” keyword
    that you use inside class-based components.
    You would not need to create an instance from a class manually.
    You just need to remember that it’s there somewhere in React’s memory.

    Function-based React elements
    do not have instances.

    A function component can still be rendered multiple times
    but React just does not associate a local instance with each render.

    It just uses the invocation of the function
    to determine what DOM element to render for the function.

Technically speaking, ReactDOM does not render
a React component or a React element in the DOM.

It renders DOM elements
backed by instances of their components.
This is true for class components.

For function components,
ReactDOM renders just DOM elements.
Function components don’t have instances (that can be accessed with this)
so when using a function component,
ReactDOM renders a DOM element
generated from the function’s returned element.

What you need to understand here
is that a React element is different from a DOM element.
A React element is just a description
of an HTML element, a React component, or a mix of these.

Okay, a better interview question might be:
When you use something like <MyComponent /> in JSX,
is that a component, an element, or an instance?

It’s an element but not a DOM element.
It’s a React element.
The clue here is that any JSX tag gets translated
to a React.createElement call.

React Components

When it comes to using React, everything boils down to components.

  1. Components are the building materials
    React uses to create website and application UI’s.
  2. Components break a UI down into reusable parts
    (one of React’s core competencies).
  3. React then renders each UI component as needed
    (separately from the others),
    which is a big part of React’s fast performance speeds.

You should use default for exporting the components

import React from 'react'
import User from 'user'

export default class MyProfile extends React.Component {
  render(){
    return (
      <User type="customer">
        //...
      </User>
    )
  }
}

With the export specifier,
the MyProfile is going to be the member
and exported to this module
and the same can be imported
without mentioning the name in other components.

import React from 'react';

class App extends React.Component{
    render(){
        return(
            <div>
            <Header/>
            <Content/>
            </div>
        );
    }
}

class Header extends React.Component{
    render(){
        return(
            <div>
            <h1> Header</h1>
            </div>
        )
    }
}

class Content extends React.Component{
    render(){
        return(
            <h2>Content</h2>
            <p>The Content Text!!!</p>
            </div>
        )
    }
}

export default App; 

Component names should start with an uppercase letter

It is necessary because components are not the DOM elements
but they are constructors.

When creating components, enclose the component name in angle brackets, as if it were a custom HTML element.
Capitalize component names, or else React will try to create them directly in the DOM, even if no HTML element with that name exists.

React.createElement accepts either a string that defines plain HTML elements, or a component.
By passing a component to React.createElement, you can combine components into more complex elements until you’ve built the whole interface.
You can replace React.createElement with JSX.
Even though JSX looks like HTML, Babel eventually converts everything to React.createElement calls.
Babel assumes elements that start with a lowercase define regular HTML elements, and elements that start with a capital are based on components.

Exceptions on React Component Naming

The lowercase tag names with a dot (property accessors)
are still considered as valid component names.

For example the below tag can be compiled to a valid component,

render(){
   return (
       <obj.component /> // `React.createElement(obj.component)`
      )
}

Presentational components
are concerned with how things look.
They generally receive data and callbacks exclusively via props.
These components rarely have their own state,
but when they do it generally concerns UI state,
as opposed to data state.

Container components
are more concerned with how things work.
These components provide the data and behavior
to presentational or other container components.
They define actions and provide these as callbacks to the presentational components.
They are also often stateful as they serve as data sources.

In HTML, form elements
such as <input>, <textarea>, and <select>
typically maintain their own state
and update it based on user input.

When a user submits a form
the values from the aforementioned elements
are sent with the form.

With React it works differently.

The component containing the form will keep track
of the value of the input in it’s state
and will re-render the component
each time the callback function
e.g. onChange is fired as the state will be updated.

An input form element whose value
is controlled by React in this way
is called a “controlled component”.

A higher-order component
is a function that takes a component
and returns a new component.

HOC’s allow you to reuse code, logic and bootstrap abstraction.

The most common is probably Redux’s connect function.

Beyond simply sharing utility libraries and simple composition,
HOCs are the best way to share behavior between React Components.

If you find yourself writing a lot of code in different places
that does the same thing,
you may be able to refactor that code into a reusable HOC.

Exercises:

  • Write a HOC that reverses it’s input.
  • Write a HOC that supplies data from an API to it’s Passed Component.
  • Write a HOC that implements shouldComponentUpdate to avoid reconciliation.
  • Write a HOC that uses React.Children.toArray to sort the children passed to it’s Passed Component.

Class Components (React before 16.8)

When React was first released to the public,
React used two kinds of components:
class components and functional components.

Functional (stateless/ presentational/ dumb) components

the most basic kind of React component,
defined by the components (unchanging) props.

When your component just receives props
and renders them to the page,
this component has no need for an internal state
and is called a ‘stateless component’.

A pure function can be used
to render the provided properties to the DOM.

Class components

Components defined as classes were more complicated
and provided more features
that allowed developers to

  1. execute component lifecycle methods
  2. and manage a component’s state:
    1. local state
    2. direct access to redux store
When to use which

This means class components are used over functional components

  1. when you need to manage state
  2. or use component lifecycle methods

To define a React component class, you need to extend React.Component:

class Welcome extends React.Component {
  render() {
    return 

Hello, {this.props.name}

; } }

The only method you must define in a React.Component subclass is called render().
All the other methods are optional.

Read more >>>

React strongly recommends against creating your own base component classes.
In React components, code reuse is primarily achieved through composition rather than inheritance.

Read more >>>

In JavaScript classes, the methods are not bound by default.

In React components declared as ES6 classes,
methods follow the same semantics as regular ES6 classes.

This means that React event handlers defined as class methods
don’t automatically bind this to the instance.

You’ll have to explicitly use .bind(this) in the constructor:

class SayHello extends React.Component {
  constructor(props) {
    super(props);
    this.state = {message: 'Hello!'};
    // This line is important!
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    alert(this.state.message);
  }

  render() {
    // Because `this.handleClick` is bound, we can use it as an event handler.
    return (
      <button onClick={this.handleClick}>
        Say hello
      </button>
    );
  }
}

This means writing ES6 classes comes with a little more boilerplate code for event handlers,
but the upside is slightly better performance in large applications.

  1. Experimental Class Properties syntax proposal with Babel
    or
    Public class fields syntax

    class SayHello extends React.Component {
      constructor(props) {
        super(props);
        this.state = {message: 'Hello!'};
      }
      // WARNING: this syntax is experimental!
      // Using an arrow here binds the method:
      handleClick = () => {
        alert(this.state.message);
      }
    
      render() {
        return (
          <button onClick={this.handleClick}>
            Say hello
          </button>
        );
      }
    }
    
    handleClick = () => {
      console.log('this is:', this)
    }
    <button onClick={this.handleClick}>
      {'Click me'}
    </button>
    

    This syntax is experimental, the syntax may change,
    or the proposal might not make it into the language.
    Read more >>>

  2. Arrow functions in callbacks
    You can use arrow functions directly in the callbacks.

    <button onClick={(event) => this.handleClick(event)}>
      {'Click me'}
    </button>
    

    The problem here is that a new callback is created each time the component renders.

  3. Keep using createReactClass

    Autobinding for createReactClass(),
    binding this is not necessary because it binds all methods:

    var SayHello = createReactClass({
      getInitialState: function() {
        return {message: 'Hello!'};
      },
    
      handleClick: function() {
        alert(this.state.message);
      },
    
      render: function() {
        return (
          <button onClick={this.handleClick}>
            Say hello
          </button>
        );
      }
    });
    
  4. You can use property initializers to correctly bind callbacks.
    This is enabled by default in create react app.

React without ES6

React doesn’t force you to use the ES6 class syntax.

If you prefer to avoid it,
you may use the create-react-class module
or a similar custom abstraction instead.

Take a look at create-react-class module:

var createReactClass = require('create-react-class');
var Greeting = createReactClass({
  render: function() {
    return <h1>Hello, {this.props.name}</h1>;
  }
});

Read more >>>

createReactClass() vs. ES6 classes

The API of ES6 classes is similar to createReactClass() with a few exceptions:

  1. defaultProps
    With functions and ES6 classes defaultProps is defined as a property on the component itself:

    class Greeting extends React.Component {
      // ...
    }
    
    Greeting.defaultProps = {
      name: 'Mary'
    };
    

    With createReactClass(), you need to define getDefaultProps() as a function on the passed object:

    var Greeting = createReactClass({
      getDefaultProps: function() {
        return {
          name: 'Mary'
        };
      },
    
      // ...
    
    });
    
  2. In ES6 classes, you can define the initial state by assigning this.state in the constructor:

    class Counter extends React.Component {
      constructor(props) {
        super(props);
        this.state = {count: props.initialCount};
      }
      // ...
    }
    

    With createReactClass(), you have to provide a separate getInitialState method that returns the initial state:

    var Counter = createReactClass({
      getInitialState: function() {
        return {count: this.props.initialCount};
      },
      // ...
    });
    
  3. In React components declared as ES6 classes,
    methods follow the same semantics as regular ES6 classes.

    This means that they don’t automatically bind this to the instance.
    You’ll have to explicitly use .bind(this) in the constructor:

    class SayHello extends React.Component {
      constructor(props) {
        super(props);
        this.state = {message: 'Hello!'};
        // This line is important!
        this.handleClick = this.handleClick.bind(this);
      }
    
      handleClick() {
        alert(this.state.message);
      }
    
      render() {
        // Because `this.handleClick` is bound, we can use it as an event handler.
        return (
          <button onClick={this.handleClick}>
            Say hello
          </button>
        );
      }
    }
    

    Autobinding for createReactClass(),
    binding this is not necessary because it binds all methods:

    var SayHello = createReactClass({
      getInitialState: function() {
        return {message: 'Hello!'};
      },
    
      handleClick: function() {
        alert(this.state.message);
      },
    
      render: function() {
        return (
          <button onClick={this.handleClick}>
            Say hello
          </button>
        );
      }
    });
    

Read more >>>

React doesn’t recommend using mixins,
as they found numerous issues in codebases using mixins.
ES6 launched without any mixin support.
Therefore, there is no support for mixins when you use React with ES6 classes.

Sometimes very different components may share some common functionality.
These are sometimes called cross-cutting concerns.
createReactClass lets you use a legacy mixins system for that.

One common use case is a component wanting to update itself on a time interval.
It’s easy to use setInterval(),
but it’s important to cancel your interval
when you don’t need it anymore to save memory.

React provides lifecycle methods that let you know
when a component is about to be created or destroyed.

Simple mixin that uses these methods to provide an easy setInterval() function
that will automatically get cleaned up when your component is destroyed:

var SetIntervalMixin = {
  componentWillMount: function() {
    this.intervals = [];
  },
  setInterval: function() {
    this.intervals.push(setInterval.apply(null, arguments));
  },
  componentWillUnmount: function() {
    this.intervals.forEach(clearInterval);
  }
};

var createReactClass = require('create-react-class');

var TickTock = createReactClass({
  mixins: [SetIntervalMixin], // Use the mixin
  getInitialState: function() {
    return {seconds: 0};
  },
  componentDidMount: function() {
    this.setInterval(this.tick, 1000); // Call a method on the mixin
  },
  tick: function() {
    this.setState({seconds: this.state.seconds + 1});
  },
  render: function() {
    return (
      <p>
        React has been running for {this.state.seconds} seconds.
      </p>
    );
  }
});

ReactDOM.render(
  <TickTock />,
  document.getElementById('example')
);

If a component is using multiple mixins
and several mixins define the same lifecycle method
(i.e. several mixins want to do some cleanup when the component is destroyed),
all of the lifecycle methods are guaranteed to be called.

Methods defined on mixins run in the order mixins were listed, followed by a method call on the component.

Read more >>>

React Class Components can be made much more concise using the class field declarations.

You can initialize local state without using the constructor
and declare class methods by using arrow functions
without the extra need to bind them.

class Counter extends Component {
  state = { value: 0 };

  handleIncrement = () => {
    this.setState(prevState => ({
      value: prevState.value + 1
    }));
  };

  handleDecrement = () => {
    this.setState(prevState => ({
      value: prevState.value - 1
    }));
  };

  render() {
    return (
      <div>
        {this.state.value}

        <button onClick={this.handleIncrement}>+</button>
        <button onClick={this.handleDecrement}>-</button>
      </div>
    )
  }
}

Read more >>>

PureComponent is exactly the same as Component
except that it handles the shouldComponentUpdate method for us.

When props or state changes,
PureComponent will do a shallow comparison
on both props and state.

Component on the other hand
won’t compare current props and state
to next out of the box.

Thus, the component will re-render by default
whenever shouldComponentUpdate is called.

When comparing previous props and state to next,
a shallow comparison will check
that primitives have the same value
(eg, 1 equals 1 or that true equals true)
and that the references are the same
between more complex javascript values like objects and arrays.

It is good to prefer PureComponent over Component
whenever we never mutate our objects.

React Component Lifecycle

Phases of applying changes to the DOM

React internally has a concept of phases
when applying changes to the DOM.

  1. Render
    The component will render without any side-effects.

    This applies for Pure components
    and in this phase, React can
    pause, abort, or restart the render.

  2. Pre-commit
    Before the component actually applies the changes to the DOM,
    there is a moment that allows React
    to read from the DOM
    through the getSnapshotBeforeUpdate().
  3. Commit
    React works with the DOM
    and executes the final lifecycles respectively

    1. componentDidMount() for mounting
    2. componentDidUpdate() for updating
    3. and componentWillUnmount() for unmounting

Component lifecycle methods

are functions that a component can execute
during specific lifecycle phases.

Every React component defines these events
as a mechanism for managing its properties, state, and rendered output.

Some of these events only happen once,
others happen more frequently.

React Lifecycle Methods Cheat Sheet

3 Phases of a React component’s lifecycle
  1. Mounting: its birth
    Mounting is a first phase of a component lifecycle.

    Component is created and is ready to mount in the browser DOM.

  2. Updating: its growth
    component is updated over time in two ways:

    1. sending the new props
    2. and updating the state
      either from setState() or forceUpdate().
  3. Unmounting: its death
    component is unmounted from the project’s DOM

    This phase includes componentWillUnmount() lifecycle method.

Read more >>>

Mounting: component’s birth
Mounting is a first phase of a component lifecycle.

Component is created and is ready to mount in the browser DOM.

The lifecycle methods are called in the following order
when an instance of a component is being created
and inserted into the DOM.

This phase consist of Render Phase and Commit Phase
and covers the following lifecycle methods:

  1. “Render phase”
    Pure and has no side effects.
    May be paused, aborted or restarted by React.

    1. initialization from constructor()
    2. static getDerivedStateFromProps()
      (less commonly used method)
    3. render()
  2. “Commit phase”
    Can work with DOM, run side effects, schedule updates.
    React updates DOM and refs

    1. componentDidMount()

Read more >>>

Updating: component’s growth
An update can be caused by changes to props or state.

Component is updated over time in two ways:

  1. sending the new props
  2. and updating the state
    either from setState() or forceUpdate().

This phase consist of Render Phase and Commit Phase
and covers the following lifecycle methods:

  1. static getDerivedStateFromProps()
    (used less often)
  2. shouldComponentUpdate()
    (used less often)
  3. render()
  4. getSnapshotBeforeUpdate()
    (used less often)
  5. componentDidUpdate()

Read more >>>

Unmounting: component’s death
component is being removed from the DOM

This method is called when a

This phase includes the following lifecycle method:

  1. componentWillUnmount()

Read more >>>

Rendering
is any time a function component gets called
(or a class-based render method gets called)
which returns a set of instructions for creating DOM.

Mounting
is when React “renders” the component for the first time
and actually builds the initial DOM from those instructions.

Re-render
is when React calls the function component again
to get a new set of instructions
on an already mounted component.

The mounting phase was just during the first render
so each subsequentrender is not also a mount,
but rather we need to figure out what in the DOM will need to be updated.

Internally, React knows
how to compare the old instructions vs the new ones
to see what actually needs to be updated in the DOM.
This is called reconciliation.

Read more >>>

Each component will get its own schedule
of mounting and re-renders
that can differ from each other.

In component architecture, it’s often true that parent nodes are aware of their children but children nodes are not aware of their parents. It’s React’s nature to re-render children nodes anytime there is a re-render in the parent. This is apart of what it means to be “reactive”.

Even though each component has its own “schedule” of mounts and renders, the relationship between parent and child is such that a child component can only possibly render and mount if its parent is mounted. When a parent component unmounts, that will cause its children to unmount.

React.render has been deprecated as of React 0.14.
Rendering is now done via ReactDOM.render.

With packages like react-native, react-art, react-canvas, and react-three, it is clear that the beauty and essence of React has nothing to do with browsers or the DOM.

To make this more clear and to make it easier to build more environments that React can render to, the main react package has been split into two: react and react-dom.

This paves the way to writing components that can be shared between the web version of React and React Native.

The react package contains React.createElement, .createClass, .Component, .PropTypes, .Children, and the other helpers related to elements and component classes. Think of these as the isomorphic or universal helpers that you need to build components.

The react-dom package has ReactDOM.render, .unmountComponentAtNode, and .findDOMNode.

Component’s render()
only creates the virtual DOM
(returns the elements that make up the component)
It does not add it to the actual browser DOM.

ReactDOM.render
does both.
It creates (or updates) the virtual DOM
(renders your components to the DOM),
and then additionally adds it to the actual browser DOM.

render()

The render() method is the only required method in a class component (React before 16.8)).

Render() is like a pipe that swallows data and outputs a representation of the UI:

 	Data --> Component --> Element

Steps:

  1. In a class component, the render function defines the UI.
    1. render() arguments
      A component’s render() method takes in no arguments
    2. render() returns
      It returns a React.createElement call.
  2. React.createElement generates a description of the UI.
    1. React.createElement arguments
      It can use either strings or a component.

      If more than one HTML element needs to be rendered,
      then they must be grouped together inside one enclosing tag.

    2. React.createElement returns
      returns the corresponding React element tree for that component
      which is the representation of the native DOM component.
Component.render() gets called

when the props or the state of a component change
and shouldComponentUpdate() returns true
(render() will not be invoked if shouldComponentUpdate() returns false)

When called, render should examine this.props and this.state.

Based on the new props and state
a new element React element tree is returned.

Component.render() returns

Component.render() method returns one of the following types:

  1. React elements
    Typically created via JSX.
    For example, <div /> and <MyComponent /> are React elements that instruct React to render a DOM node, or another user-defined component, respectively.
  2. Arrays and fragments
    Let you return multiple elements from render. See the documentation on fragments for more details.
  3. Portals
    Let you render children into a different DOM subtree. See the documentation on portals for more details.
  4. String and numbers
    These are rendered as text nodes in the DOM.
  5. Booleans or null
    Render nothing. (Mostly exists to support return test && <Child > pattern, where test is boolean.)
Render as a pure function

The render() function should be pure,
meaning that it does not modify component state,
it returns the same result each time it’s invoked,
and it does not directly interact with the browser.

If you need to interact with the browser,
perform your work in componentDidMount() or the other lifecycle methods instead.
Keeping render() pure makes components easier to think about.

Read more >>>

ReactDOM.render()
ReactDOM.render(element, container[, callback])

Renders a React element into the DOM
in the supplied container
and returns a reference to the component
(or null for stateless components).

Components combine multiple elements and describe a piece of UI as a function of data.
Babel eventually converts everything to React.createElement calls.
React.createElement returns a description of the UI.
ReactDOM.render takes this description of the UI and constructs the actual matching DOM nodes:

 	Element --> Renderer --> UI

ReactDOM.render creates a new tree of DOM nodes that matches the description returned by React.createElement.
It places the result inside the DOM node you pass as its second argument.

If the React element was previously rendered into container,
this will perform an update on it
and only mutate the DOM as necessary
to reflect the latest React element.

If the optional callback is provided,
it will be executed
after the component is rendered or updated.

Before mounting any DOM elements to the container though,
React performs a diff between the passed element tree
and the currently mounted DOM
to determine which of the DOM nodes in the currently mounted DOM
have to be updated
in order to match the newly passed element tree.

Read more >>>

constructor(props)
When to call constructor(props)

If you don’t initialize state and you don’t bind methods,
you don’t need to implement a constructor for your React component.

The constructor for a React component is called before it is mounted.

Avoid introducing any side-effects or subscriptions in the constructor.
For those use cases, use componentDidMount() instead.

Reason for using constructor(props)

Typically, in React constructors are only used for two purposes:

  1. Initializing local state by assigning an object to this.state.
  2. Binding event handler methods to an instance.
super(props)

When implementing the constructor for a React.Component subclass,
you should call super(props) before any other statement.
Otherwise, this.props will be undefined in the constructor, which can lead to bugs.

Setting initial state in constructor()

You should not call setState() in the constructor().

Instead, if your component needs to use local state,
assign the initial state to this.state directly in the constructor:

constructor(props) {
  super(props);
  // Don't call this.setState() here!
  this.state = { counter: 0 };
  this.handleClick = this.handleClick.bind(this);
}

Constructor is the only place where you should assign this.state directly.
In all other methods, you need to use this.setState() instead.

Avoid copying props into state! This is a common mistake:

constructor(props) {
 super(props);
 // Don't do this!
 this.state = { color: props.color };
}

The problem is that it’s both unnecessary (you can use this.props.color directly instead),
and creates bugs (updates to the color prop won’t be reflected in the state).

Only use this pattern if you intentionally want to ignore prop updates.
In that case, it makes sense to rename the prop to be called initialColor or defaultColor.
You can then force a component to “reset” its internal state by changing its key when necessary.
Read more on Fully uncontrolled component with a key >>>

React’s post on avoiding derived state and what to do if you need state to depend on props >>>

React’s post on constructor(props) >>>

React’s reconciliation algorithm
assumes that without any information to the contrary,
if a custom component appears in the same place on subsequent renders,
it’s the same component as before,
so it reuses the previous instance
rather than creating a new one.

Place in Component Lifecycle

componentDidMount() is invoked
immediately after a component is mounted
(inserted into the tree)
= executed after first rendering.

Usage
  1. Fetching remote data
    If you need to load data from a remote endpoint,
    this is a good place to instantiate the network request
    (e.g. all AJAX requests).
  2. Event listeners
    Event listeners set up should occur here.
    E.g., Listening for DOM or state updates.
  3. Subscriptions
    This method is a good place to set up any subscriptions.
    If you do that, don’t forget to unsubscribe in componentWillUnmount().
  4. Initialization that requires DOM nodes

    Extra re-rendering
    You may call setState() immediately in componentDidMount().
    It will trigger an extra rendering,
    but it will happen before the browser updates the screen.

    This guarantees that even though the render() will be called twice in this case,
    the user won’t see the intermediate state.

    Performance issues
    Use this pattern with caution because it often causes performance issues.
    In most cases, you should be able to assign the initial state in the constructor() instead.

    Measuring a DOM node before render
    It can, however, be necessary for cases like modals and tooltips
    when you need to measure a DOM node before rendering something
    that depends on its size or position.

React’s post on componentDidMount() >>>

Place in Component Lifecycle

componentDidUpdate() is invoked immediately after updating occurs.
This method is not called for the initial render.

componentDidUpdate(prevProps, prevState, snapshot)
Usage
  1. Updating DOM in response to prop or state changes
    Mostly it is used to /operate on the DOM
    when the component has been updated.
  2. Fetching remote data with comparison with previous props
    This is also a good place to do network requests
    as long as you compare the current props to previous props
    (e.g. a network request may not be necessary if the props have not changed).
componentDidUpdate(prevProps) {
  // Typical usage (don't forget to compare props):
  if (this.props.userID !== prevProps.userID) {
    this.fetchData(this.props.userID);
  }
}
Infinite loop if no condition

You may call setState() immediately in componentDidUpdate()
but note that it must be wrapped in a condition,
or you’ll cause an infinite loop.

Extra re-rendering

It would also cause an extra re-rendering
which, while not visible to the user,
can affect the component performance.

If you’re trying to “mirror” some state to a prop coming from above,
consider using the prop directly instead.
Read more about why copying props into state causes bugs.

Using componentDidUpdate() with getSnapshotBeforeUpdate()

componentDidUpdate() will not be invoked if shouldComponentUpdate() returns false.

If your component implements the getSnapshotBeforeUpdate() lifecycle (which is rare),
the value it returns will be passed as a third “snapshot” parameter to componentDidUpdate().
Otherwise this parameter will be undefined.

static getDerivedStateFromProps(props, state)

It should return an object to update the state, or null to update nothing.

Place in Component Lifecycle

getDerivedStateFromProps is invoked
right before calling the render method,
both on the initial mount
and on subsequent updates.

This method is fired on every render, regardless of the cause.
This is in contrast to UNSAFE_componentWillReceiveProps,
which only fires when the parent causes a re-render
and not as a result of a local setState.

Usage

This method exists for rare use cases
where the state depends on changes in props over time
(where you need derived state).

For example, it might be handy for implementing a <Transition7gt; component
that compares its previous and next children
to decide which of them to animate in and out.

Alternatives for getDerivedStateFromProps

Deriving state leads to verbose code
and makes your components difficult to think about.

Make sure you’re familiar with simpler alternatives:

  1. side effects on prop change – componentDidUpdate
    If you need to perform a side effect
    (for example, data fetching or an animation)
    in response to a change in props,
    use componentDidUpdate lifecycle instead.
  2. re-compute data on prop change – memoization
    If you want to re-compute some data only when a prop changes,
    use a memoization helper instead.
  3. reset state on prop change – fully controlled or fully uncontrolled component with a key
    If you want to “reset” some state when a prop changes,
    consider either making a component fully controlled
    or fully uncontrolled with a key instead.
Reusing getDerivedStateFromProps() in other class methods

This method doesn’t have access to the component instance.

If you’d like, you can reuse some code
between getDerivedStateFromProps() and the other class methods
by extracting pure functions of the component props and state
outside the class definition.

Read more >>>

shouldComponentUpdate(nextProps, nextState)
Place in Component Lifecycle

shouldComponentUpdate() is invoked before rendering
when new props or state are being received.

This method is not called for the initial render
or when forceUpdate() is used.

Usage

React’s default behavior: shouldComponentUpdate() true
shouldComponentUpdate() defaults to true to determine that the component will be updated.
The default React’s behavior is to re-render on every state change,
and in the vast majority of cases you should rely on the default behavior.

shouldComponentUpdate() false
If component doesn’t need to render
after state or props are updated,
you can return false value.

Use shouldComponentUpdate() to let React know
if a component’s output is not affected
by the current change in state or props.

shouldComponentUpdate() as performance optimization

This method only exists as a performance optimization.

shouldComponentUpdate() vs. Pure Component
Do not rely on shouldComponentUpdate() to “prevent” a rendering, as this can lead to bugs.

Consider using the built-in PureComponent
instead of writing shouldComponentUpdate() by hand.

PureComponent performs a shallow comparison of props and state,
and reduces the chance that you’ll skip a necessary update.

If you are confident you want to write it by hand,
you may compare this.props with nextProps and this.state with nextState
and return false to tell React the update can be skipped.

Returning false does not prevent child components
from re-rendering when their state changes
.

React doesn’t recommend doing deep equality checks
or using JSON.stringify() in shouldComponentUpdate().
It is very inefficient and will harm performance.

Currently, if shouldComponentUpdate() returns false,
then UNSAFE_componentWillUpdate(), render(), and componentDidUpdate()
will not be invoked.

In the future React may treat shouldComponentUpdate()
as a hint rather than a strict directive,
and returning false may still result in a re-rendering of the component.

Read more >>>

 getSnapshotBeforeUpdate(prevProps, prevState)

A snapshot value (or null) should be returned.
Any value returned by this lifecycle will be passed as a parameter to componentDidUpdate().

Place in Component Lifecycle

getSnapshotBeforeUpdate() is invoked
right before the most recently rendered output
is committed to the DOM.

Usage

It enables your component
to capture some information from the DOM (e.g. scroll position)
before it is potentially changed.

This use case is not common, b
ut it may occur in UIs like a chat thread
that need to handle scroll position in a special way.

class ScrollingList extends React.Component {
  constructor(props) {
    super(props);
    this.listRef = React.createRef();
  }

  getSnapshotBeforeUpdate(prevProps, prevState) {
    // Are we adding new items to the list?
    // Capture the scroll position so we can adjust scroll later.
    if (prevProps.list.length < this.props.list.length) {
      const list = this.listRef.current;
      return list.scrollHeight - list.scrollTop;
    }
    return null;
  }

  componentDidUpdate(prevProps, prevState, snapshot) {
    // If we have a snapshot value, we've just added new items.
    // Adjust scroll so these new items don't push the old ones out of view.
    // (snapshot here is the value returned from getSnapshotBeforeUpdate)
    if (snapshot !== null) {
      const list = this.listRef.current;
      list.scrollTop = list.scrollHeight - snapshot;
    }
  }

  render() {
    return (
      <div ref={this.listRef}>{/* ...contents... */}</div>
    );
  }
}

It is important to read the scrollHeight property in getSnapshotBeforeUpdate
because there may be delays
between “render” phase lifecycles (like render)
and “commit” phase lifecycles (like getSnapshotBeforeUpdate and componentDidUpdate).

Read more >>>

Place in Component Lifecycle

componentWillUnmount() is invoked immediately before a component is unmounted and destroyed.

Usage

Perform any necessary cleanup in this method, such as

  1. invalidating timers,
  2. canceling any outgoing network requests,
  3. removing all event listeners associated with the component,
  4. or cleaning up any subscriptions

that were created in componentDidMount().

setState() in componentWillUnmount()

You should not call setState() in componentWillUnmount()
because the component will never be re-rendered.
Once a component instance is unmounted, it will never be mounted again.

Read more >>>

The following lifecycle methods
are considered to be unsafe coding practices
and cause problems with async rendering.

Lifecycle Method Description
componentWillMount
(deprecated)
Most commonly used for App configuration in your root component.
componentWillReceiveProps
(deprecated)
Acts on particular prop changes to trigger state transitions
componentWillUpdate
(deprecated)
Rarely used.
It can be used instead of componentWillReceiveProps
on a component that also has shouldComponentUpdate
(but no access to previous props).

React Hooks

On February 16, 2019, React 16.8 was released to the public.
The release introduced React Hooks.

They let you use state and other React features without writing a class.
Hooks provide a more direct API to all of the fundamental the React concepts:
props, state, context, refs, and lifecycle.

Motivation
Hooks solve a wide variety of seemingly unconnected problems in React
that Facebook encountered over five years
of writing and maintaining tens of thousands of components.

  1. It’s hard to reuse stateful logic between components
    React doesn’t offer a way to “attach” reusable behavior to a component (for example, connecting it to a store). If you’ve worked with React for a while, you may be familiar with patterns like render props and higher-order components that try to solve this. But these patterns require you to restructure your components when you use them, which can be cumbersome and make code harder to follow. If you look at a typical React application in React DevTools, you will likely find a “wrapper hell” of components surrounded by layers of providers, consumers, higher-order components, render props, and other abstractions.
    While we could filter them out in DevTools, this points to a deeper underlying problem: React needs a better primitive for sharing stateful logic.

    With Hooks, you can extract stateful logic from a component so it can be tested independently and reused. Hooks allow you to reuse stateful logic without changing your component hierarchy.

  2. Complex components become hard to understand
    Facebook often had to maintain components that started out simple but grew into an unmanageable mess of stateful logic and side effects. Each lifecycle method often contains a mix of unrelated logic. For example, components might perform some data fetching in componentDidMount and componentDidUpdate. However, the same componentDidMount method might also contain some unrelated logic that sets up event listeners, with cleanup performed in componentWillUnmount. Mutually related code that changes together gets split apart, but completely unrelated code ends up combined in a single method. This makes it too easy to introduce bugs and inconsistencies.

    In many cases it’s not possible to break these components into smaller ones because the stateful logic is all over the place. It’s also difficult to test them. This is one of the reasons many people prefer to combine React with a separate state management library. However, that often introduces too much abstraction, requires you to jump between different files, and makes reusing components more difficult.

    To solve this, Hooks let you split one component into smaller functions based on what pieces are related (such as setting up a subscription or fetching data), rather than forcing a split based on lifecycle methods. You may also opt into managing the component’s local state with a reducer to make it more predictable.

    Read more about useEffect Hook >>>

  3. Classes confuse both people and machines
    In addition to making code reuse and code organization more difficult, we’ve found that classes can be a large barrier to learning React. You have to understand how this works in JavaScript, which is very different from how it works in most languages. You have to remember to bind the event handlers. Without unstable syntax proposals, the code is very verbose. People can understand props, state, and top-down data flow perfectly well but still struggle with classes. The distinction between function and class components in React and when to use each one leads to disagreements even between experienced React developers.

Read more >>>

Hooks let you use more of React’s features without having to use classes.

Hook Description
useState lets you add React state to function components.
It returns an array with a getter and a setter.

syntax:

const [count, setCount] = React.useState(0);

vs. class component:

this.state = {
  count: 0
};
    
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
  Increase Count
</button>
useEffect Lets you perform side effects in function components.
Passing an empty array as the second argument to useEffect
is equivalent to using componentDidMount.

If you pass a value to the array
it will only call the useEffect function
when the value in the array updates.

useEffect(() => {
  // do something when the component mounts
}, []);

Tricky React Lifecycle Questions

You can listen to the resize event in componentDidMount()
and then update the dimensions (width and height).

You should remove the listener in componentWillUnmount() method.

class WindowDimensions extends React.Component {
  constructor(props){
    super(props);
    this.updateDimensions = this.updateDimensions.bind(this);
  }
   
  componentWillMount() {
    this.updateDimensions()
  }

  componentDidMount() {
    window.addEventListener('resize', this.updateDimensions)
  }

  componentWillUnmount() {
    window.removeEventListener('resize', this.updateDimensions)
  }

  updateDimensions() {
    this.setState({width: window.innerWidth, height: window.innerHeight})
  }

  render() {
    return <span>{this.state.width} x {this.state.height}</span>
  }
}

You need to use setInterval() to trigger the change,
but you also need to clear the timer
when the component unmounts
to prevent errors and memory leaks.

componentDidMount() {
  this.interval = setInterval(() => this.setState({ time: Date.now() }), 1000)
}

componentWillUnmount() {
  clearInterval(this.interval)
}

Returning null from a component’s render method
means nothing will be displayed,
but it does not affect the firing of the component’s lifecycle methods.

If the amount of times the component re-renders is an issue,
there are two options available.

  1. Manually implementing a check in the shouldComponentUpdate lifecycle method hook.
    shouldComponentUpdate(nextProps, nextState){
      // Do some check here
      return resultOFCheckAsBoolean
    }
    
  2. Or using React.PureComponent instead of React.Component

    React.PureComponent implements shouldComponentUpdate()
    with a shallow prop and state comparison.

    This enables you to avoid re-rendering the component
    with the same props and state.

Fiber, the React’s reconciliation algorithm,
decides when to begin and quit rendering.

There are two lifecycle methods
that could be considered for making an AJAX call.

componentWillMount

One of them is componentWillMount,
but this means React may begin calling componentWillMount
at different circumstances
at whenever point it senses that it needs to.
This would clearly be a bad formula for AJAX requests.

Using componentWillMount you can’t guarantee
that the AJAX request resolves
before the component mounts.

If it doesn’t, that would mean
that you’d be trying to setState
on an unmounted component,
which would not work.

componentDidMount

componentDidMount
is where an AJAX request should be made in a React component

This method will be executed
when the component “mounts”
(is added to the DOM) for the first time.

This method is only executed once during the component’s life.

Making your AJAX request in componentDidMount
will guarantee that there is a component to update.

At this point,
the component’s data and reactivity features
are available to operate,
however, the component has not rendered yet.

You can use setState()
to update your component
when the data is retrieved.

E.g., employees list fetched from API and set local state:

class MyComponent extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      employees: [],
      error: null
    }
  }

  componentDidMount() {
    fetch('https://api. example. com /items')
      .then(res => res.json())
      .then(
        (result) => {
          this.setState({
            employees: result.employees
          })
        },
        (error) => {
          this.setState({ error })
        }
      )
  }

  render() {
    const { error, employees } = this.state
    if (error) {
      return <div>Error: {error.message}</div>;
    } else {
      return (
        <ul>
          {employees.map(employee => (
            <li key={employee.name}>
              {employee.name}-{employee.experience}
            </li>
          ))}
        </ul>
      )
    }
  }
}

React Error Handling

Error boundaries
are React components that catch JavaScript errors anywhere in their child component tree,
og those errors,
and display a fallback UI instead of the component tree that crashed.

Errors caught by error boundaries

Error boundaries catch errors
during rendering,
in lifecycle methods,
and in constructors of the whole tree below them.

Error boundaries only catch errors in the components below them in the tree.
An error boundary can’t catch an error within itself.

Create error boundaries

A class component becomes an error boundary
if it defines either (or both) of the lifecycle methods
static getDerivedStateFromError() or componentDidCatch().

Updating state from these lifecycles
lets you capture an unhandled JavaScript error in the below tree
and display a fallback UI.

Only use error boundaries for recovering from unexpected exceptions;
don’t try to use them for control flow.

Read more on Error Boundaries >>>
Read more on Error Boundaries >>>
Read more on Error Handling in React 16 >>>

These methods are called when there is an error during rendering,
in a lifecycle method,
or in the constructor of any child component.

  1. static getDerivedStateFromError()
  2. componentDidCatch()

	  
static getDerivedStateFromError(error)
Place in Component Lifecycle

This lifecycle is invoked after an error has been thrown by a descendant component.
It receives the error that was thrown as a parameter and should return a value to update state.

getDerivedStateFromError() is called during the “render” phase,
so side-effects are not permitted.
For those use cases, use componentDidCatch() instead.

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    // Update state so the next render will show the fallback UI.
    return { hasError: true };
  }

  render() {
    if (this.state.hasError) {
      // You can render any custom fallback UI
      return 

Something went wrong.

;     }     return this.props.children;   } }

Read more on getDerivedStateFromError() >>>  
     

   

 

	  
componentDidCatch(error, info)

componentDidCatch() receives two parameters:

  1. error
    The error that was thrown.
  2. info
    An object with a componentStack key containing information about which component threw the error.

In the event of an error,
you can render a fallback UI with componentDidCatch() by calling setState,
but this will be deprecated in a future release.
Use static getDerivedStateFromError() to handle fallback rendering instead.

Place in Component Lifecycle

This lifecycle is invoked after an error has been thrown by a descendant component.

componentDidCatch() is called during the “commit” phase,
so side-effects are permitted.

It should be used for things like logging errors:

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    // Update state so the next render will show the fallback UI.
    return { hasError: true };
  }

  componentDidCatch(error, info) {
    // Example "componentStack":
    //   in ComponentThatThrows (created by App)
    //   in ErrorBoundary (created by App)
    //   in div (created by App)
    //   in App
    logComponentStackToMyService(info.componentStack);
  }

  render() {
    if (this.state.hasError) {
      // You can render any custom fallback UI
      return <h1>Something went wrong.</h1>;
    }

    return this.props.children;
  }
}

Read more on componentDidCatch() >>>
     

   

 

State and Props

Object has state if its behavior is influenced by its history.
(Harold Abelson and Gerald Jay Sussman with Julie Sussman. Structure and Interpretation of Computer Programs. MIT Press, Cambridge, MA, 2nd Edition, 1996.)

React defines a series of constraints
that help you keep the application structure predictable.

this.state
You must store the state that affects the UI
in a dedicated object that you access with this.state.

this.setState
Once you set the initial value,
you update this.state with the this.setState function.

setState can only update the state of the component where you call it.

To update other components,
pass the state or values you compute based on the state as props.

prop drilling
Since you can only pass props to child components,
updates only flow from components down to their children.
This constraint makes the consequences of a state update more predictable,
as you only need to look at the child components.

With functions and ES6 classes
defaultProps
is defined as a property on the component itself:

class Greeting extends React.Component {
  // ...
}

Greeting.defaultProps = {
  name: 'Mary'
};

In ES6 classes, you can define the initial state
by assigning this.state in the constructor:

class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = {count: props.initialCount};
  }
  // ...
}

State Props
Definition State is essentially an object
that holds data and determines
how the component renders and behaves.
(short for properties)
are a Component’s configuration.

Props are a way for the components
to communicate with each other.

While the props are mostly data,
callback functions can be passed down as well.

Mutability State is mutable

and is used for mutable data
or data that will change over time,
as a result of user events/actions.

Props are immutable
as far as the Component receiving them is concerned.
Controlled by Starts with a default value
when a component mounts.

State is private and fully controlled by the component.

Props are received from above.

A component isn’t able to change its props,
but it has to put together the props of its child components.

The React philosophy is
that props should be
immutable and top-down.

This means that a parent
can send any prop values to a child,
but the child can’t modify received props.

setState()
does not immediately mutate this.state
but creates a pending state transition.

Accessing this.state after calling this method
can potentially return the existing value.

There is no guarantee
of synchronous operation of calls to setState
and calls may be batched for performance gains.

This is because setState alters the state and causes rerendering.

This can be an expensive operation
and making it synchronous
might leave the browser unresponsive.

Thus the setState calls are asynchronous
as well as batched for better UI experience and performance.

Callback function can optionally be passed to setState as a second argument.
It advised to pass a callback function to setState as opposed to an object.

A callback function is invoked when setState has finished
and the component is re-rendered.

setState is asynchronous

Because this.props and this.state
may be updated asynchronously,
you should not rely on their values
for calculating the next state.

However, rather than relying solely on the callback function,
one should use another lifecycle method.

If you try to update state directly then it won’t re-render the component.

//Wrong

this.state.message = 'Hello world'
Instead use setState() method. It schedules an update to a component's state object. When state changes, the component responds by re-rendering.

//Correct

this.setState({ message: 'Hello World' })

setState()

When you use setState()
the current and previous states are merged.

replaceState()

replaceState()
throws out the current state,
and replaces it with only what you provide.

setState() vs. replaceState()

Usually setState() is used
unless you really need
to remove all previous keys for some reason.

You can also set state to false/null in setState()
instead of using replaceState().

Render Props
is a simple technique
for sharing code between components
using a prop
whose value is a function.

The below component uses render prop which returns a React element.

<DataProvider render={data => (
  <h1>{`Hello ${data.target}`}</h1>
)}/>

Libraries such as React Router and DownShift are using this pattern.

When several components
need to share the same changing data
then it is recommended to lift the shared state up
to their closest common ancestor.

That means if two child components
share the same data from its parent,
then move the state to parent
instead of maintaining local state
in both of the child components.

Yes, it is possible.

The best way to perform this task
is by using the spread operator.

It can also be done
with listing the properties
but this is a complex process.

If the ownProps parameter is specified,
React Redux will pass the props
that were passed to the component
into your connect functions.

So, if you use a connected component:

import ConnectedComponent from './containers/ConnectedComponent';

<ConnectedComponent user={'john'} />

The ownProps inside your mapStateToProps() and mapDispatchToProps() functions will be an object:

{ user: 'john' }

You can use this object to decide what to return from those functions.

By default, when your component’s state or props change,
your component will re-render.

If your render() method depends on some other data,
you can tell React that the component needs re-rendering
by calling forceUpdate().

It is recommended to avoid all uses of forceUpdate()
and only read from this.props and this.state in render().

component.forceUpdate(callback)

When we spread props
we run into the risk of adding unknown HTML attributes,
which is a bad practice.

Instead we can use prop destructuring with …rest operator,
so it will add only required props.

For example,

const ComponentA = () =>
  <ComponentB isDisplay={true} className={'componentStyle'} />

const ComponentB = ({ isDisplay, ...domProps }) =>
  <div {...domProps}>{'ComponentB'}</div>

A child class constructor cannot make use of this
until super() has been called.

Also, ES2015 class constructors have to call super() if they are subclasses.

The reason for passing props to super()
is to enable you to access this.props in the child constructor.

Passing props:

class MyComponent extends React.Component {
  constructor(props) {
    super(props)
    console.log(this.props) // { name: 'John', age: 42 }
  }
}

Not passing props:

class MyComponent extends React.Component {
  constructor(props) {
    super()
    console.log(this.props) // undefined
    console.log(props) // { name: 'John', age: 42 }
  }

  render() {
    // no difference outside constructor
    console.log(this.props) // { name: 'John', age: 42 }
  }
}

this.props is different only within the constructor.
It would be the same outside the constructor.

In JSX expressions that contain both an opening tag and a closing tag,
the content between those tags
is passed to components automatically
as a special prop: props.children.

There are a number of methods available in the React API to work with this prop.

These include:

  1. React.Children.map
  2. React.Children.forEach
  3. React.Children.count
  4. React.Children.only
  5. React.Children.toArray

If you are using ES6 or the Babel transpiler to transform your JSX code then you can accomplish this with computed property names.

handleInputChange(event) {
  this.setState({ [event.target.id]: event.target.value })
}

If the props on the component are changed without the component being refreshed, the new prop value will never be displayed because the constructor function will never update the current state of the component. The initialization of state from props only runs when the component is first created.

The below component won’t display the updated input value:

class MyComponent extends React.Component {
  constructor(props) {
    super(props)

    this.state = {
      records: [],
      inputValue: this.props.inputValue
    };
  }

  render() {
    return <div>{this.state.inputValue}</div>
  }
}

Using props inside render method will update the value:

class MyComponent extends React.Component {
  constructor(props) {
    super(props)

    this.state = {
      record: []
    }
  }

  render() {
    return <div>{this.props.inputValue}</div>
  }
}

Recommended approach is to use Array.prototype.filter() method.

For example, let’s create a removeItem() method for updating the state.

removeItem(index) {
  this.setState({
    data: this.state.data.filter((item, i) => i !== index)
  })
}

Calling setState() with an object to merge with state:

  1. Using Object.assign() to create a copy of the object:
    const user = Object.assign({}, this.state.user, { age: 42 })
    this.setState({ user })
    
  2. Using spread operator:
    const user = { ...this.state.user, age: 42 }
    this.setState({ user })
    

Calling setState() with a function:

this.setState(prevState => ({
  user: {
    ...prevState.user,
    age: 42
  }
}))

State Management

React  helps developers divide UIs into multiple components,
but doesn’t have a specific way to keep track of state.

Redux is a library that compliments React
by providing a single source of truth
to keep the state of the entire application
in a single store which is simply a JavaScript object.

Redux is a predictable state container for JavaScript apps based on the Flux design pattern. Redux can be used together with ReactJS, or with any other view library. It is tiny (about 2kB) and has no dependencies.

The only way to change the state
is by sending actions from your application
and then writing reducers for these actions
that modify the state.

The entire state transition is kept inside reducers
and should not have any side-effects.

Redux follows three fundamental principles:

  1. Single source of truth

    The state of your whole application
    is stored in an object tree
    within a single store.

    The single state tree makes it easier
    to keep track of changes over time
    and debug or inspect the application.

  2. State is ready only

    The only way to change the state
    is to emit an action,
    an object describing what happened.

    This ensures that neither the views
    nor the network callbacks
    will ever write directly to the state.

  3. Changes are made with pure functions

    To specify how the state tree is transformed by actions,
    you write reducers.

    Reducers are pure functions
    that take the previous state and an action,
    and return the next state.

The single source of truth
refers to the store used for storing the app’s entire state at one place.

The benefits of the single source of truth include the facts
that all the components stored there
receive updates from the store itself,
it is easier to keep track of their changes,
as well as debug and inspect the application.

  1. Redux adds a solid structure to React code,
    making your code easier to maintain,
    and your intended coding results more predictable.
  2. Redux includes developer tools
    that allow you to track your web application’s performance in real time.

    From actions to state changes,
    developers can track everything going on
    in the application in real time.

  3. Like React, Redux has strong community support and robust ecosystem.

Most of the applications have several top-level directories:

  1. Components Used for “dumb” React components unaware of Redux
  2. Containers Used for “smart” React components connected to Redux
  3. Actions Used for all action creators, where file name corresponds to part of the app
  4. Reducers Used for all reducers, where file name corresponds to state key
  5. Store Used for store initialization This structure works well for small and mid-level size apps

Component
is a class or function component
that describes the presentational part of your application.

Container
is an informal term for a component
that is connected to a Redux store.

Containers subscribe to Redux state updates
and dispatch actions,
and they usually don’t render DOM elements;
they delegate rendering to presentational child components.

Action


Actions are payloads of information that send data from our application to our store. They are the only source of information for the store. We send them to the store using store.dispatch(). Primarly, they are just an object describes what happened in our app.

Reducer

Reducers specify how the application’s state changes in response to actions sent to the store. Remember that actions only describe what happened, but don’t describe how the application’s state changes. So this place determines how state will change to an action.

Store

The Store is the object that brings Action and Reducer together. The store has the following responsibilities: Holds application state; Allows access to state via getState(); Allows state to be updated viadispatch(action); Registers listeners via subscribe(listener); Handles unregistering of listeners via the function returned bysubscribe(listener).

The store is a javascript object that holds application state.

Along with this it also has the following responsibilities:

  1. Allows access to state via getState()
  2. Allows state to be updated via dispatch(action)
  3. Registers listeners via subscribe(listener)
  4. Handles unregistering of listeners via the function returned by subscribe(listener)

We need to keep our application state as small as possible.

E.g. use local state for text input values,
we don’t need to store every single character that user types in in the store,
it is enifficient,
difficult to debug,
and slows down the application.

Export the store from the module
where it was created with createStore().

Also, it shouldn’t pollute the global window object.

store = createStore(myReducer)

export default store

The best way to access your store in a component
is to use the connect() function,
that creates a new component
that wraps around your existing one.

This pattern is called Higher-Order Components,
and is generally the preferred way
of extending a component’s functionality in React.

This allows you
to map state and action creators to your component,
and have them passed in automatically as your store updates.

Let’s take an example of <FilterLink> component using connect:

import { connect } from 'react-redux'
import { setVisibilityFilter } from '../actions'
import Link from '../components/Link'

const mapStateToProps = (state, ownProps) => ({
  active: ownProps.filter === state.visibilityFilter
})

const mapDispatchToProps = (dispatch, ownProps) => ({
  onClick: () => dispatch(setVisibilityFilter(ownProps.filter))
})

const FilterLink = connect(
  mapStateToProps,
  mapDispatchToProps
)(Link)

export default FilterLink

Due to it having quite a few performance optimizations
and generally being less likely to cause bugs,
the Redux developers almost always recommend using connect()
over accessing the store directly (using context API).

class MyComponent {
  someMethod() {
    doSomethingWith(this.context.store)
  }
}

Actions are plain javascript objects.

They must have a type
indicating the type of action being performed.

In essence, actions are payloads of information
that send data from your application to your store.

A reducer is simply a pure function
that takes the previous state and an action,
and returns the next state.

(previousState, action) => newState

It’s called a reducer because it’s the type of function you would pass to Array.prototype.reduce(reducer, ?initialValue). It’s very important that the reducer stays pure. Things you should never do inside a reducer:

Mutate its arguments;
Perform side effects like API calls and routing transitions;
Call non-pure functions, e.g. Date.now() or Math.random().

Reducers always return the accumulation of the state
(based on all previous and current actions).

Therefore, they act as a reducer of state.

Each time a Redux reducer is called,
the state and action are passed as parameters.

This state is then reduced (or accumulated)
based on the action,
and then the next state is returned.

You could reduce a collection of actions
and an initial state (of the store)
on which to perform these actions
to get the resulting final state.

Selectors
are functions that take Redux state as an argument
and return some data to pass to the component.

E.g., to get user details from the state:

const getUserData = state => state.user.data;

You can use ES7 static field to define constant.

class MyComponent extends React.Component {
  static DEFAULT_PAGINATION = 10
}

Static fields are part of the Class Fields stage 3 proposal.

Constants

  1. prevent you from introducing silly bugs
    caused by typos,
    in which case, you will get a ReferenceError immediately.
  2. allow you to easily find all usages
    of that specific functionality
    across the project when you use an IDE.

Normally we will save them in a single file (constants.js or actionTypes.js):

export const ADD_TODO = 'ADD_TODO'
export const DELETE_TODO = 'DELETE_TODO'
export const EDIT_TODO = 'EDIT_TODO'
export const COMPLETE_TODO = 'COMPLETE_TODO'
export const COMPLETE_ALL = 'COMPLETE_ALL'
export const CLEAR_COMPLETED = 'CLEAR_COMPLETED'

In Redux you use them in two places:

  1. During action creation

    Let’s take actions.js:

    import { ADD_TODO } from './actionTypes';
    
    export function addTodo(text) {
      return { type: ADD_TODO, text }
    }
    
  2. In reducers

    Let’s create reducer.js:

    import { ADD_TODO } from './actionTypes'
    
    export default (state = [], action) => {
      switch (action.type) {
        case ADD_TODO:
          return [
            ...state,
            {
              text: action.text,
              completed: false
            }
          ];
        default:
          return state
      }
    }
    

You need to pass initial state as second argument to createStore

const rootReducer = combineReducers({
  todos: todos,
  visibilityFilter: visibilityFilter
});

const initialState = {
  todos: [{id:123, name:'sudheer', completed: false}]
};

const store = createStore(
  rootReducer,
  initialState
);

You need to write a root reducer in your application
which will delegate handling the action
to the reducer generated by combineReducers().

For example, let us take rootReducer()
to return the initial state after USER_LOGOUT action.

As we know, reducers are supposed to return the initial state
when they are called with undefined as the first argument,
no matter the action.

const appReducer = combineReducers({
  /* your app's top-level reducers */
})

const rootReducer = (state, action) => {
  if (action.type === 'USER_LOGOUT') {
    state = undefined
  }

  return appReducer(state, action)
}

In case of using redux-persist,
you may also need to clean your storage.

Redux-persist keeps a copy of your state
in a storage engine.

First, you need to import the appropriate storage engine
and then, to parse the state
before setting it to undefined
and clean each storage state key.

const appReducer = combineReducers({
  /* your app's top-level reducers */
})

const rootReducer = (state, action) => {
  if (action.type === 'USER_LOGOUT') {
    Object.keys(state).forEach(key => {
      storage.removeItem(`persist:${key}`)
    })

    state = undefined
  }

  return appReducer(state, action)
}

mapStateToProps()
is a utility which helps your component
to get updated state

const mapStateToProps = (state) => {
  return {
    todos: getVisibleTodos(state.todos, state.visibilityFilter)
  }
}

mapDispatchToProps()
is a utility which helps your component
to fire an action event
(dispatching action to change application state):

const mapDispatchToProps = (dispatch) => {
  return {
    onTodoClick: (id) => {
      dispatch(toggleTodo(id))
    }
  }
}

It is recommend to use the “object shorthand” form
for the mapDispatchToProps

Redux will
wrap it in another function that looks like

(…args) => dispatch(onTodoClick(…args))

and pass that wrapper function as a prop to your component.

 const mapDispatchToProps = ({
   onTodoClick
 })
 

There are a few ways
of binding action creators
to dispatch() in mapDispatchToProps().

const mapDispatchToProps = (dispatch) => ({
 action: () => dispatch(action())
})
const mapDispatchToProps = (dispatch) => ({
 action: bindActionCreators(action, dispatch)
})
const mapDispatchToProps = { action }

The third option is just a shorthand for the first one.

You need to follow two steps to use your store in your container:

  1. Use mapStateToProps():
    It maps the state variables from your store to the props that you specify.
  2. Connect the above props to your container:
    The object returned by the mapStateToProps function
    is connected to the container.
    You can import connect() from react-redux.
import React from 'react'
import { connect } from 'react-redux'
class App extends React.Component {
  render() {
    return <div>{this.props.containerData}</div>
  }
}
function mapStateToProps(state) {
  return { containerData: state.data }
}
export default connect(mapStateToProps)(App)

The @ symbol
is a JavaScript expression
used to signify decorators.

Decorators make it possible
to annotate and modify
classes and properties
at design time.

Let’s take an example setting up Redux without and with a decorator.

Without decorator

import React from 'react'
import * as actionCreators from './actionCreators'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'

function mapStateToProps(state) {
  return { todos: state.todos }
}

function mapDispatchToProps(dispatch) {
  return { actions: bindActionCreators(actionCreators, dispatch) }
}

class MyApp extends React.Component {
  // ...define your main app here
}

export default connect(mapStateToProps, mapDispatchToProps)(MyApp)

With decorator

import React from 'react'
import * as actionCreators from './actionCreators'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'

function mapStateToProps(state) {
  return { todos: state.todos }
}

function mapDispatchToProps(dispatch) {
  return { actions: bindActionCreators(actionCreators, dispatch) }
}

@connect(mapStateToProps, mapDispatchToProps)
export default class MyApp extends React.Component {
  // ...define your main app here
}
The above examples are almost similar except the usage of decorator. The decorator syntax isn't built into any JavaScript runtimes yet, and is still experimental and subject to change. You can use babel for the decorators support.

Redux Ecosystem

We can use Context in our application directly and is going to be great for passing down data to deeply nested components which what it was designed for. Whereas Redux is much more powerful and provides a large number of features that the Context Api doesn’t provide.

Also, React Redux uses context internally but it doesn’t expose this fact in the public API. So we should feel much safer using context via React Redux than directly because if it changes, the burden of updating the code will be on React Redux instead developer responsibility.

Flux is a pattern and Redux is a library.

Flux is a fancy name for the observer pattern modified a little bit to fit React, but Facebook released a few tools to aid in implementing the Flux pattern, so the following is the difference between using these tools (which is commonly referred to as using Flux) and using Redux.

Both Flux and Redux have actions. Actions can be compared to events (or what trigger events). In Flux, an action is a simple JavaScript object, and that’s the default case in Redux too, but when using Redux middleware, actions can also be functions and promises.

With Flux it is a convention to have multiple stores per application; each store is a singleton object. In Redux, the convention is to have a single store per application, usually separated into data domains internally (you can create more than one Redux store if needed for more complex scenarios).

Flux has a single dispatcher and all actions have to pass through that dispatcher. It’s a singleton object. A Flux application cannot have multiple dispatchers. This is needed because a Flux application can have multiple stores and the dependencies between those stores need a single manager, which is the dispatcher.

Redux has no dispatcher entity. Instead, the store has the dispatching process baked in. A Redux store exposes a few simple API functions, one of them is to dispatch actions.

In Flux, the logic of what to do on the data based on the received action is written in the store itself. The store also has the flexibility of what parts of the data to expose publicly. The smartest player in a Flux app is the store.

In Redux, the logic of what to do on the data based on the received actions is in the reducer function that gets called for every action that gets dispatched (through the store API). A store can’t be defined without a reducer function. A Redux reducer is a simple function that receives the previous state and one action, and it returns the new state based on that action. In a Redux app, you can split your reducer into simpler functions as you would do with any other function. The smartest player in Redux is the reducer.

In Redux, also, there isn’t a lot of flexibility about what to expose as the store’s state. Redux will just expose whatever returned from the store’s reducer. This is one constraint.

The other bigger constraint is that the store’s state cannot be mutable (or really, shouldn’t be). There is no such constraint in Flux, you can mutate the state as you wish. The state’s immutability, in Redux, is achieved easily by making the reducers pure functions (with no side effects). Redux reducers always copy the state they receive and returns a modified version of the state’s copy, not the original object itself. While this is a big constraint, it makes life much easier long term.

Relay is similar to Redux
in that they both use a single store.

The main difference is
that Relay only manages state originated from the server,
and all access to the state
is used via GraphQL queries (for reading data)
and mutations (for changing data).

Relay caches the data for you
and optimizes data fetching,
by fetching only changed data and nothing more.

These libraries are very different
and accomplish very different purposes,
but there are some vague similarities.

Redux
is a tool for managing state
throughout the application.

It is usually used as an architecture for UIs.

RxJS
is a reactive programming library.

It is usually used as a tool
to accomplish asynchronous tasks in JavaScript.

Think of it as an alternative to Promises.

Redux uses the Reactive paradigm
because the Store is reactive.

The Store observes actions from a distance,
and changes itself.

RxJS also uses the Reactive paradigm,
but instead of being an architecture,
it gives you basic building blocks,
Observables,
to accomplish this pattern.

You can use applyMiddleware where you can pass each piece of middleware as a new argument. So you just need to pass each piece of middleware you’d like. For example, you can add Redux Thunk and logger middlewares as an argument as below,

import { createStore, applyMiddleware } from 'redux'
const createStoreWithMiddleware = applyMiddleware(ReduxThunk, logger)(createStore);

Redux thunk is middleware
that allows you to write action creators
that return a function instead of an action.

The thunk can then be used
to delay the dispatch of an action
if a certain condition is met.

This allows you to handle the asynchronous dispatching of actions.

The inner function receives the store methods dispatch and getState as parameters.

To enable Redux Thunk, we need to use applyMiddleware()

import{ createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers/index';

const store= createStore(
     rootReducer,
     applyMiddleware(thunk)
);

Redux-Saga
is a library that aims to make side effects
(i.e. asynchronous things like data fetching
and impure things like accessing the browser cache)
in React/Redux applications
easier and better.

Both Redux Thunk and Redux Saga
take care of dealing with side effects.

In most of the scenarios,
Thunk uses Promises to deal with them,
whereas Saga uses Generators.

Thunk is simple to use
and Promises are familiar to many developers,
Sagas/Generators are more powerful
but you will need to learn them.

But both middleware can coexist,
so you can start with Thunks
and introduce Sagas when/if you need them.

Redux-Thunk middleware allows to define async actions.

E.g., fetching account data as an AJAX call using fetch API:

export function fetchAccount(id) {
  return dispatch => {
    dispatch(setLoadingAccountState()) // Show a loading spinner
    fetch(`/account/${id}`, (response) => {
      dispatch(doneFetchingAccount()) // Hide loading spinner
      if (response.status === 200) {
        dispatch(setAccount(response.json)) // Use a normal function to set the received state
      } else {
        dispatch(someError)
      }
    })
  }
}

function setAccount(data) {
 return { type: 'SET_Account', data: data }
}

Saga
is like a separate thread in your application,
that’s solely responsible for side effects.

Redux-saga is a redux middleware,
which means this thread
can be started, paused and cancelled
from the main application
with normal Redux actions,
it has access to the full Redux application state
and it can dispatch Redux actions as well.

Both call() and put()
are effect creator functions.

call()
is used to create effect description,
which instructs middleware
to call the promise.

put()
creates an effect,
which instructs middleware
to dispatch an action to the store.

Let’s take example of how these effects work for fetching particular user data.

function* fetchUserSaga(action) {
  // `call` function accepts rest arguments, which will be passed to `api.fetchUser` function.
  // Instructing middleware to call promise, it resolved value will be assigned to `userData` variable
  const userData = yield call(api.fetchUser, action.userId)

  // Instructing middleware to dispatch corresponding action.
  yield put({
    type: 'FETCH_USER_SUCCESS',
    userData
  })
}

Redux DevTools
is a live-editing
time travel environment
for redux
with hot reloading,
action replay,
and customizable UI.

Main Features of Redux DevTools
  1. Lets you inspect every state and action payload
  2. Lets you go back in time by “cancelling” actions
  3. If you change the reducer code,
    each “staged” action will be re-evaluated
  4. If the reducers throw,
    you will see during which action this happened,
    and what the error was
  5. With persistState() store enhancer,
    you can persist debug sessions
    across page reloads

Routing and History

A Router is particularly useful
for creating and defining multiple routes.

When you type a specific URL
that matches a path of any route
defined inside the router,
you will be redirected to that particular route.

Basically, you will bypass all the other routes
and get to the one you need.

React Router
is a powerful routing library built on top of React.

It is highly useful
for adding new screens and flows to the application
while keeping the URL
in sync with data displayed on the web page.

The React Router has a simple API
and it maintains a standardized behavior and structure
for developing single page web apps.

  1. Just like how React is based on components,
    in React Router v4, the API is ‘All About Components’.

    A Router can be visualized as a single root component
    (<BrowserRouter>)
    in which we enclose the specific child routes
    (<route>).

  2. No need to manually set History value:
    In React Router v4, all we need to do
    is wrap our routes within the <BrowserRouter> component.
  3. The packages are split:
    Three packages one each for Web, Native and Core.
    This supports the compact size of our application.
    It is easy to switch over based on a similar coding style.

React Router
is a wrapper around the history library
which handles interaction with the browser’s window.history
with its browser and hash histories.

It also provides memory history
which is useful for environments
that don’t have global history,
such as mobile app development (React Native)
and unit testing with Node.

A history instance has two methods for navigation purpose.
If you think of the history as an array of visited locations,

  1. push() will add a new location to the array
  2. replace() will replace the current location in the array with the new one.

There are three different ways to achieve programmatic routing/navigation within components.

Using the withRouter() higher-order function

The withRouter() higher-order function
will inject the history object
as a prop of the component.

This object provides push() and replace() methods
to avoid the usage of context.

import { withRouter } from 'react-router-dom' // this also works with 'react-router-native'

const Button = withRouter(({ history }) => (
  <button
    type='button'
    onClick={() => { history.push('/new-location') }}
  >
    {'Click Me!'}
  </button>
))
Using <Route> component and render props pattern

The <Route> component
passes the same props as withRouter(),
so you will be able to access the history methods
through the history prop.

import { Route } from 'react-router-dom'

const Button = () => (
  <Route render={({ history }) => (
    <button
      type='button'
      onClick={() => { history.push('/new-location') }}
    >
      {'Click Me!'}
    </button>
  )} />
)
Using context

This option is not recommended
and is treated as an unstable API.

const Button = (props, context) => (
  <button
    type='button'
    onClick={() => {
      context.history.push('/new-location')
    }}
  >
    {'Click Me!'}
  </button>
)

Button.contextTypes = {
  history: React.PropTypes.shape({
    push: React.PropTypes.func.isRequired
  })
}

React Router v4 provides below 3 <Router> components:

  1. <BrowserRouter>
  2. <HashRouter>
  3. <MemoryRouter>

The above components will create
browser, hash, and memory history instances.

React Router v4
makes the properties and methods
of the history instance
associated with your router
available through the context
in the router object.

<div> is used to encapsulate multiple routes inside the Router.

The switch keyword is used
when you want to display only a single route
to be rendered amongst the several defined routes.

<switch> tag matches the typed URL
with the defined routes in sequential order.

When the first match is found,
it renders the specified route
bypassing all the other routes.

You have to wrap your Route’s in a <Switch> block
because <Switch>
uniquely renders each route exclusively.

First you need to add Switch to your imports,
then define the routes within <Switch> block.

import { Switch, Router, Route } from 'react-router'

<Router>
  <Switch>
    <Route {/* ... */} />
    <Route {/* ... */} />
  <Switch>
<Router>

Create a module that exports a history object
and import this module across the project,
e.g., history.js file:

import { createBrowserHistory } from 'history'

export default createBrowserHistory({
  /* pass a configuration object here if needed */
})

Import the above history.js inside index.js file.
(Use <Router> component instead of built-in routers).

import { Router } from 'react-router-dom'
import history from './history'
import App from './App'

ReactDOM.render((
  <Router history={history}>
    <App />
  </Router>
), holder)

You can also use push method of history object
similar to built-in history object:

// some-other-file.js
import history from './history'

history.push('/go-here')

query strings library

The ability to parse query strings
was taken out of React Router v4
because there have been user requests over the years
to support different implementation.

So the decision has been given to users
to choose the implementation they like.

The recommended approach
is to use query strings library.

const queryString = require('query-string');
const parsed = queryString.parse(props.location.search);
URLSearchParams

You can also use URLSearchParams if you want something native:

const params = new URLSearchParams(props.location.search)
const foo = params.get('name')

You should use a polyfill for IE11.

While navigating you can pass props to the history object.
The search property is used to pass query params in push() method.

this.props.history.push({
  pathname: '/template',
  search: '?name=sudheer',
  state: { detail: response.data }
})

Add a listener on the history object to record each page view:

history.listen(function (location) {
  window.ga('set', 'page', location.pathname + location.search)
  window.ga('send', 'pageview', location.pathname + location.search)
})



Resources:

  1. https://reactjs.org/docs/react-component.html
  2. https://github.com/the-road-to-learn-react/
  3. React for Real: Front-End Code, Untangled by Ludovico Fischer
  4. dev.to
  5. tms-outsource.com
  6. madanswer.com
  7. stackoverflow.com
  8. reacttraining.com
  9. www.freecodecamp.org
  10. hashnode.com
  11. indepth.dev

Leave a Reply or Comment

Your email address will not be published. Required fields are marked *