Concepts of React JS — Part 1

📄 Table of Contents

▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬ ✦ ✦ ✦ ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬

React JS version 15.0
React Life Cycles

◉ state vs props

state is mutable in nature, should NOT be accessed & modified from child components and can only be used inside the component.

The state of a parent component can be passed a prop to the child. They are referencing the same value, but only the parent component can update it.

props are data passed in from a parent component to child components. props are IMmutable in nature.props are read-only in the child component that receives them.

What happens when setState() function is called?

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

Ideally, when you have a parent and a child class but NO setState(), then

However, (introduction of setState()) setState() will run functions in this order:

* shouldComponentUpdate()
* componentWillUpdate()
* render()
* componentDidUpdate()

Note: If your component is receiving props it will run the componentWillRecieveProps() function with the above functions.

◉ Container vs Functional Components

or Stateful vs Stateless Components

The stateless components (or ‘functional’ or ‘dumb’ do not have state of their own, and receive state from container components and just print out the data you pass to them.

So when you should you either a stateful component or a stateless one?

If you just want to render plain data, go for stateless components. Of course, you can also use stateful components for the task. However, it’s not worth it.

source: https://itnext.io/controlled-vs-uncontrolled-components-in-react-5cd13b2075f9

◉ Controlled vs Un-Controlled Components

The controlled component in action!

The controlled component in action!

We don’t need a form element on the page for the component to be a controlled component.

When changes are made to any of the input elements that have an event handler, the handler is fired.

The alternative is UNcontrolled components, where form data is handled by the DOM itself. Uncontrolled components act more like traditional HTML form elements. The data for each input element is stored in the DOM, not in the component. Instead of writing an event handler for all of your state updates, you use a ref to retrieve values from the DOM.

Refs provide a way to access DOM nodes or React elements created in the render method.

  1. Refs cannot be used on functional components as there is no instance.
  2. Refs can be used inside functional components.
  3. There are a few good use cases for refs: Managing focus, text selection, or media playback.

◉ Composition over Inheritance

Composition is recommended over Inheritance.

A component can be called by another container component. And when calling a component, you can pass to it some props. We also learned that different container components can pass different props to the same component (Heading in our case).

The code above just demonstrated a simple use-case of React Composition.

In React using Composition and Props gives you all the flexibility that you would need. React does not say Composition is better than Inheritance. Composition just fits better within the React’s component structure.

◉ Constructor:-

You can then initialize your state, setting the default values. You can even base the state on the props:

Note that using a constructor is optional, and you can initialise your state like so if your Babel setup has support for class fields:

This approach is widely preferred. You can still base your state off props:

getDerivedStateFromProps vs CWRProps

A common misconception is that getDerivedStateFromProps and componentWillReceiveProps are only called when props “change” rather these lifecycles are called any time a parent component re-renders, regardless of whether the props are “different” from before.

Source: https://hackernoon.com/replacing-componentwillreceiveprops-with-getderivedstatefromprops-c3956f7ce607

  • “this” not accessible: getDerivedStateFromProps is a static method which is invoked after a component is instantiated as well as when it receives new props. Since it is a static method, you cannot access “this” inside this method neither you can access any other class method.
  • setState() not allowed: Unlike componentWillReceiveProps, you CANNOT set state inside this method, so the only way to update state is returning an object. If you don’t want to update any state, simply return null.

how componentWillReceiveProps works

We compare nextProps.someValue with this.props.someValue and if both are different then we perform some operation, setState and call this.classMethod();.

◉ when to use CWRProps actually??

Meaning that, if you re-render that component passing a different value as a prop, the component will not react accordingly, because that component has already been constructed, so the child component will not update and re-render i.e.,the component will keep the state from the first time it was rendered. It’s very error prone.

This is where componentWillReceiveProps comes in handy.

componentWillReceiveProps({someProp}) {
this.setState({...this.state, someProp})
}

Now, when receiving updated props from the parent the child will re-render.

how getDerivedStateFromProps works

Notice an object is being returned in the getDerivedStateFromProps to update the state and no class method is being called. We’re using componentDidUpdate to check if a path is changed or not and accordingly create a new firebase connection and listen to new path.

Source: https://stackoverflow.com/questions/49617486/how-to-use-lifecycle-method-getderivedstatefromprops-as-opposed-to-componentwill

About the removal of componentWillReceiveProps: you should be able to handle its uses with a combination of getDerivedStateFromProps and componentDidUpdate, see the React blog post for example migrations.

ComponentWillReceiveProps vs getDerivedStateFromProps

CWRProps vs shouldComponentUpdate

  • only when the props have changed and when this is not an initial rendering.. If only the state changes, this method won’t be called.
  • Also, this won’t decide if the component should re-render. You can use this method to, for example, change some state, or make an API call.

shouldComponentUpdate will be called

  • every time a prop or something in the state changes (or React think that has changed).
  • It’s function is to determine if the component should re-render by returning a boolean: true if the component should re-render (this is the default return value), or false if it shouldn’t. You can access the current and next state and props, to compare and decide if it really should re-render or not. You should not use this method for other reason.
ComponentWillReceiveProps vs ShouldComponentUpdate

What’s new in React 16.0 ?

[1]. new core architecture “Fiber”.

[2]. Fragments & strings (simply return an array of elements, and string)

[3]. error boundaries (componentDidCatch(error, info)),

[4]. portals (allows us to renders children in any DOM node regardless of it’s location in the DOM.)

[5]. async rendering (which is to be released soon)

[6]. incremental rendering of virtual DOM

[7]. Reduced File Size (react + react-dom is 109 kb, 32% size decrease compared to the previous version ).

Is DOM slow, Really?

What is slow, however, is the layout that browsers have to do whenever the DOM changes. Every time the DOM changes, browser need to recalculate the CSS, do layout, and repaint the web page. This is what takes time.

Browser makers are continually working to shorten the time it takes to repaint the screen. The biggest thing that can be done is to minimize and batch the DOM changes that make redraws necessary.

This strategy of reducing and batching DOM changes, taken to another level of abstraction, is the idea behind React’s Virtual DOM.

Why need to bind event handlers in class components in react? Blame JavaScript, Not “React” for this. “this” is undefined in constructor.

◉ Ref / keys

Both keys and refs are used to identify particular elements in the DOM, however their purposes are different.

some of the best cases for using refs are: managing focus, text selection, or media playback, triggering animations, and integrating with third-party DOM libraries.

this ref handling is run before ComponentDidMount so that when page is mounted, this is ready to use.

keys are useful when working with dynamically created components or when your lists are altered(changed, are added, or are removed) by the users.

If you choose not to assign an explicit key to list items then React will default to using indexes as keys.However, we don’t recommend using indexes for keys if the order of items may change.

Context API (v 16.3 onwards, Provider + Consumer concept)

source: https://medium.com/free-code-camp/a-beginners-guide-to-getting-started-with-react-c7f34354279e

let understand why Facebook felt the need to build a library called React ?

Let’s get into the details of this example and understand how that would work. Let’s say that I have 20 comments in my comments array. The comments array is the source of truth, and it reflects the current state at any point in time. When the user adds a new comment, we need to modify this comments’ array once the new comment has been successfully added to the database. The comments array now holds 21 comments.

Oh yeah, we also need to write code to update the DOM to reflect the current state (Assume we’re using Vanilla JavaScript or jQuery here. Cool stuff coming up next!). This means that the comments DOM container is subscribed to the comments array. It should be modified when there is any change in the comments array. We can safely say that the comments array is the model here, and the comments container is the view.

Let’s add something more to this — hundreds of div elements are subscribed to this comments model, which means that we need to write code to update each of these div elements.

function updateCommentsSubscriber (response) {
commentsArr = [ ...response ]
// commentsArr = ['Comment 1', 'Comment 2', ...]
var firstDiv = document.getElementById('first')
firstDiv.innerHTML = commentsArr.length
var secondDiv = document.getElementById('second')
secondDiv.innerHTML = commentsArr.toString()
...
}

Sigh! Imagine if this happened at the scale at which Facebook operates. Whenever we have a new element that is subscribed to that model, we’d have to write code to make changes to that element. This approach is not scalable.

Facebook dealt with the scalability and DOM slowness issue by building a library called React. React was first deployed on the Newsfeed section of Facebook in 2011, and then on Instagram in 2012. It was open-sourced in 2013 and has been applauded by the community worldwide ever since.

React follows a component-based structure.Each of the components that we define in React extends the basic functionalities of the native React Component.

React follows a Composition-based model.

Simplest React Component

class HelloReact extends React.Component {
render () {
return (
<div>Hello React!</div>
)
}
}
ReactDOM.render(<HelloReact>, document.getElementById('app'))

The above example will print Hello React! on the screen. HelloReact is called a component in React. The render method inside this component returns the DOM representation.

It’s not a coincidence that I wrote HTML in JavaScript. <div>Hello React!</div> inside render method is a JSX syntax. It lets us write HTML in JavaScript.

Rendering Child Nodes using the map function

renderComments (commentsArr) {

commentsArr = [{
id: 1,
text: "I'm a comment!"
}]

return (
<div class='comments-container'>
{
commentsArr.map (function (comment) {
return <div key={comment.id}>{comment.text}</div>
})
}
</div>
)
}

Compiling JSX to JavaScript

JSX is transpiled to JavaScript statements by the Babel plugin before React encounters them. Transpilation is the process of converting one source language to another. So, all that React sees is simple JavaScript statements.

◉ ES6

JavaScript follows a function-level scoping.

A variable declared inside a function can be used in the entire function, but not outside of it.

Let’s consider an example that will help us understand function-level scoping:

function pokemon (id) { //id = 12
if (id === 12) {
var pokemonObj = {
id: 12,
name: 'butterfree',
height: 11,
weight: 22,
abilities: [
{
name: 'tinted-lens'
}
]
}
}
return pokemonObj
}

The above pokemon method takes id as the parameter, and returns pokemonObj if the id is equal to 12. Go ahead and run this function in your browser console.

If you execute pokemon(12), it prints the pokemonObj as expected. However, if you execute pokemon(13), it doesn't display an error, and instead prints undefined.

◉ Classes

Let’s build a class to evaluate berries:

class Berries {    constructor (berries) {
this.berries = berries
}
getSize () {
return this.berries.size
}
getGrowthTime () {
return this.berries.growth_time
}
}
const cherries = new Berries(berries)
cherries.getSize() // 20
cherries.getGrowthTime() // 3

We’ve wrapped the relevant berries methods inside the class Berries.

The statement const cherries = new Berries(berries) instantiates the Berries class and create an Object of type Berries.

The input passed to the Berries constructor is the berries object we've created earlier. We can use methods defined in the Berries class on this object.

Now that we’ve learned most of the common ES6 techniques, we can use them in the following sections.

◉ React Elements vs React Components

The browser doesn’t understand React. Like we saw earlier, JSX is converted to JavaScript statements for creating a DOM node.

With this statement:

React.createElement("div", { className: 'heading' }, "Hello React!")

The div DOM node isn't yet appended to the DOM. The above statement is converted to plain JavaScript object as:

{
type: 'div',
props: {
className: 'heading',
children: 'Hello React!'
}
}

These objects are called React Elements.

They contain two important keys:

type specifies the type of the DOM node. It can be div, span, p, and so on.

props describes the properties of that element. In this case, we have className and children.

The nested elements can be specified as the value of the children key.

ReactDOM does the work of converting these React Elements to actual DOM nodes and also updates them accordingly.

React elements are immutable and are cheap to create. If there is any change in a React Element, its older instance is destroyed, and a newer one is created from scratch.

However, the corresponding DOM node is not always destroyed to make room for a newer one. DOM operations are expensive, and hence they should be avoided at all possible instances.

ReactDOM does a great job here. It creates new React elements because creating them is cheap, however, it efficiently updates only the part of the real DOM node that is modified.

React uses a diffing algorithm to find out what needs to be updated to the DOM. We’ll learn more about it in the Virtual DOM section.

Let’s go through what we’ve learned so far:

  • JSX is an HTML-like syntax that is used in React components. It’s just a representation of the DOM node and doesn’t actually append elements to the DOM.
  • The Babel plugin transpiles it to plain JavaScript statements as React.createElement.
  • The React.createElement statements are further converted into JavaScript objects.
  • ReactDOM efficiently updates the real DOM using the objects created above.

ReactComponents are great, we would love to have plenty of them since they are easy to manage. But they have no access to the virtual DOM — and we would like to do as much as possible there.

Whenever a ReactComponent is changing the state, we want to make as little changes to the “real” DOM as possible. So this is how React deals with it.

The ReactComponent (stateful) is converted to the ReactElement (stateless + immutable) using ReactDOM. Now, the ReactElement can be inserted to the virtual DOM, compared and updated fast and easily. How exactly — well, that’s the job of the diff algorithm. The point is — it’s done faster than it would be in the “regular” DOM.

When React knows the diff — it’s converted to the low-level (HTML DOM) code, which is executed in the DOM. This code is optimised per browser.

◉ Anti-patterns

  • A common misconception is that getDerivedStateFromProps and componentWillReceiveProps are only called when props “change”. These lifecycles are called any time a parent component re-renders, regardless of whether the props are “different” from before.

Pure Components in React

In fact, if you have a functional component and you want React to treat it as a pure component, you will have to convert the functional component to a class component that extends React.PureComponent.

Hence, Pure components have some performance improvements and render optimizations since React implements the shouldComponentUpdate() method for them with a shallow comparison for props and state.

It is the same as (normal) Component except that Pure Components take care of shouldComponentUpdate by itself, it does the shallow comparison on the state and props data. If the previous state and props data is the same as the next props or state, the component is NOT Re-rendered.

A React component can be considered pure if it renders the same output for the same state and props. For class components like this, React provides the PureComponent base class. Class components that extend the React. PureComponent class are treated as pure components.

class ImpureComponent extends React.PureComponent {…}

By default, React Components re-renders in following scenarios:

  • “setState” is called in Component
  • “props” values are updated
  • this.forceUpdate() is called

However, in the case of Pure Components, the React components do not re-render blindly without considering the updated values of React “props” and “state”. If updated values are the same as previous values, render is NOT triggered.

Note: In case of React Pure Component, the changes in react “props” and “state” is Shallow Compared.

Use Pure Components, in the case when the props and state changes are made to primitive type variable, state and props changes to reference variable may lead to incorrect results and inconsistent rendering.

Using the { pure } HOC from Re-compose

If you are already familiar with the Recompose package, then you know that it provides a wide collection of higher-order components (HOCs) that makes it very useful when dealing with functional components.

The Recompose package exports a { pure } HOC that tries to optimize a React component by preventing updates on the component unless a prop has changed, using shallowEqual() to test for changes.

Why should data be IMMutable ?

React’s reconciliation process determines if a component should re-render or if it needs a way to keep track of the changes.

Comparing reference variables can lead to a problem — as only the address of the object are compared before and after the update. Since we’re comparing references, the address still remains the same and the Pure Component does not detect any changes and does not re-render. We can resolve this by creating a new instance of the state variable if it represents the reference type.

If we want to copy the object into a new object, we can use the spread operator (…)

https://blog.bitsrc.io/react-16-lifecycle-methods-how-and-when-to-use-them-f4ad31fb2282

Experience with Front-end Technologies and MERN / MEAN Stack. Working on all Major UI Frameworks like React, Angular.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store