Skip to main content

New advanced features of Reactjs 16+ version

New advanced features of Reactjs 16+ version

There are many new advanced features introduce by Facebook in Reactjs 16+ version.

1. Code-Splitting 

2. Error Boundaries

3. Context

4. Profiler

5. Static Type Checking

6. Fragments

7. Strict Mode

8. Portals

9. Forwarding Refs

10. Web Components


Code-Splitting

First question comes in mind why do we need code-splitting. Bundling is a great and web application use bundling mechanism. As your app grows, your bundle will grow too. You need to take care about bundle side to avoid to takes long time to load app. 

In general you can split your bundle by using webpack or other tool. But reactjs 16 provides many ways to code-split into bundles.

React.lazy

React.lazy function lets you render a dynamic import as a regular component. Imported component will render on demand.


import React from "react";
//before
import TestComponent from "./TestComponent";
//After
const TestComponent = React.lazy(() => import('./TestComponent'));

React.lazy function must return Promise which resolves to a module with a default  export containing a React component. Lazy component should render inside Suspense component.


import React,{Suspense} from "react";
//normal import
import HeaderComponent from "./HeaderComponent";
//dynamic import, lazy import must be import in the end 
const TestComponent = React.lazy(() => import('./TestComponent'));

function MyComponent() {
    return (
      <div>
        <Suspense fallback={<div>Loading...</div>}>
          <HeaderComponent />
          <TestComponent/>
        </Suspense>
      </div>
    );
  }
In the Suspense component you can use fallback to display any message during loading the component.You can also use you custom component as a fallback.
Note: make sure all the dynamic/lazy import should be import after normal imports otherwise you will compile error. React.lazy and Suspense not yet available for server side rendering. If you want to code split server side, use Loadable Component as reactjs recommendation.

Route-based code splitting

In single page app web page render based on routing, you can split code in routing by using React.lazy function. Your app code will split into separate bundles based on app page and page will load into browser on demand through routing. It helps to load app very fast and improve the app performance.

routes.js
import React, { Suspense, lazy } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';

const HomeComponent = lazy(() => import('./HomeComponent'));
const AboutComponent = lazy(() => import('./AboutComponent'));

const App = () => (
  <Router>
    <Suspense fallback={<div>Loading...</div>}>
      <Switch>
        <Route exact path="/" component={HomeComponent}/>
        <Route path="/about" component={AboutComponent}/>
      </Switch>
    </Suspense>
  </Router>
);

Error Boundaries

Error boundary is used to handle run time front-end error and display meaningful message to user. You can create a number of error boundaries according to requirement and you can log your error easily in error boundary component. 

MyErrorBoundary.js

import React,{Component} from "react";
import {logError} from "./logService";

class MyErrorBoundary 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, errorInfo) {
      // You can also log the error to an error reporting service
      logError(error, errorInfo);
    }
  
    render() {
      if (this.state.hasError) {
        // You can render any custom fallback UI
        return <h1>Something went wrong.</h1>;
      }
  
      return this.props.children; 
    }
  }


MyComponent.js
import React,{Suspense} from "react";
//normal import
import HeaderComponent from "./HeaderComponent";
import MyErrorBoundary from "./MyErrorBoundary";
//dynamic import, lazy import must be import in the end 
const TestComponent = React.lazy(() => import('./TestComponent'));

function MyComponent() {
    return (
      <div>
       <MyErrorBoundary>
        <Suspense fallback={<div>Loading...</div>}>
          <HeaderComponent />
          <TestComponent/>
        </Suspense>
        </MyErrorBoundary>
      </div>
    );
  }


Context

Context is used to pass the data through the component tree without having to pass props down manually at every level. 

In general React app, data is passed top-down (parent to child)  via props, but this can be  cumbersome for certain types of props i.e. UI theme, locale preferences etc that can be required in many components in application. Context solve this issue by using context api createContext to pass data.



First you should create context object by using context api createContext and use provider to pass the data and finally get the data in component by using consumer.

import React,{createContext} from "react";
// Create a context for the current theme (with "dark" as the default).
const ThemeContext = createContext('dark');

class App extends React.Component {
  render() {
    // Use a Provider to pass the current theme to the tree below.
    // Any component can read it, no matter how deep it is.
    // In this example, we're passing "light" as the current value.
    return (
      <ThemeContext.Provider value="light">
        <Toolbar />
      </ThemeContext.Provider>
    );
  }
}

// A component in the middle doesn't have to
// pass the theme down explicitly anymore.
function Toolbar() {
  return (
    <div>
      <ThemedButton />
    </div>
  );
}

class ThemedButton extends React.Component {
  render() {
    return(
        <ThemeContext.Consumer>
        {value=> <Button theme={value} />}          
        </ThemeContext.Consumer>
        )
  }
}

Profiler

The Profiler is used to measures how React application renders and what the cost of rendering. The purpose of Profiler is to help to identify the parts of application that are slow and benefit from optimization such as memoization.

Profiler can be added anywhere in react tree to measure the cost of rendering that part of tree. You need to pass two props an id (string) and onRender callback function which React call any time a component within the tree commits and update. You can many profilers as much as you require.

Note: Profiler adds some overhead, so it is disabled in production build.

render(
  <App>
    <Profiler id="nav" onRender={callback}>
      <Navigation {...props} />
    </Profiler>
    <Profiler id="main" onRender={callback}>
      <Main {...props} />
    </Profiler>
  </App>
);


Static Type Checking

Static type checking is used to identify certain types of problem before you ever run your code. To solve types problems reactjs suggest to use Flow or TypeScript instead of PropsTypes for large code base. 


Fragments

As reactjs render single element so you need to wrap multiple elements into single element. Fragment wrap list of children without adding extra node to the DOM.  Major problem comes when you want to group multiple components like Table component which have divide into multiple component Column and Row component. It cause the issue with adding extra node into dom. But Fragment solve the issue , Fragment can be used as <React.Fragment>children</React.Fragment> or <>children</>.



render() {
    return (
      <React.Fragment>
        <ChildA />
        <ChildB />
        <ChildC />
      </React.Fragment>
    );
  }

  //or 

  render() {
    return (
      <>
        <ChildA />
        <ChildB />
        <ChildC />
      </>
    );
  }


Strict Mode

Strict Mode is a tool which is used to highlight the potential problems in the application. It does not render any UI. It activates additional checks warnings for its descendants.

Strict Mode help to identify below problems
  • Detect legacy context API
  • Identify components with unsafe lifecycles
  • Detecting unexpected side effects
  • Warning about deprecated findDOMNode usage 
Note: strict mode check are run in development mode only, they don't impact in production mode.


import React from 'react';

function ExampleApplication() {
  return (
    <div>
      <Header />
      <React.StrictMode>
        <div>
          <ComponentX />
          <ComponentY />
        </div>
      </React.StrictMode>
      <Footer />
    </div>
  );
}


Portals

Portals is the first-class way to render children into DOM node that exits outside the DOM hierarchy of the parent component. There are some case where you can use Portals like tooltip and modal etc.

createPortal function is used to create portal which takes two parameters child and container. 


<div id="app"></div>
<div id="modal"></div>
// These two containers are siblings in the DOM
const appRoot = document.getElementById('app');
const modalRoot = document.getElementById('modal');

// Let's create a Modal component that is an abstraction around
// the portal API.
class Modal extends React.Component {
  constructor(props) {
    super(props);
    // Create a div that we'll render the modal into. Because each
    // Modal component has its own element, we can render multiple
    // modal components into the modal container.
    this.el = document.createElement('div');
  }

  componentDidMount() {
    // Append the element into the DOM on mount. We'll render
    // into the modal container element (see the HTML tab).
    modalRoot.appendChild(this.el);
  }

  componentWillUnmount() {
    // Remove the element from the DOM when we unmount
    modalRoot.removeChild(this.el);
  }
  
  render() {
    // Use a portal to render the children into the element
    return ReactDOM.createPortal(
      // Any valid React child: JSX, strings, arrays, etc.
      this.props.children,
      // A DOM element
      this.el,
    );
  }
}

// The Modal component is a normal React component, so we can
// render it wherever we like without needing to know that it's
// implemented with portals.
class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {showModal: false};
    
    this.handleShow = this.handleShow.bind(this);
    this.handleHide = this.handleHide.bind(this);
  }

  handleShow() {
    this.setState({showModal: true});
  }
  
  handleHide() {
    this.setState({showModal: false});
  }

  render() {
    // Show a Modal on click.
    // (In a real app, don't forget to use ARIA attributes
    // for accessibility!)
    const modal = this.state.showModal ? (
      <Modal>
        <div className="modal">
          <div>
            With a portal, we can render content into a different
            part of the DOM, as if it were any other React child.
          </div>
          This is being rendered inside the #modal-container div.
          <button onClick={this.handleHide}>Hide modal</button>
        </div>
      </Modal>
    ) : null;

    return (
      <div className="app">
        This div has overflow: hidden.
        <button onClick={this.handleShow}>Show modal</button>
        {modal}
      </div>
    );
  }
}

ReactDOM.render(<App />, appRoot);


Forwarding Refs

Forwarding refs is used for automatically passing a ref through a component to one of its children. It can be useful some kinds of components, especially in reusable components.
createRef function is used to create ref and forwardRef function is used to forward ref.


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

// You can now get a ref directly to the DOM button:
const ref = React.createRef();
<FancyButtonComponent ref={ref}>Click me!</FancyButtonComponent>;


Web Components

Web components provide encapsulation for reusable components, while React provides a declarative library that keep in sync with your data. Developer is free to use React in your web components or web components in React or both.

Web Component is very useful for micro front-end architecture, no matter in which library or framework your application build. Expose your application as a web component and use it as a html tag. Let suppose there are four micro applications , two app build by using React and other two with Vue or angular. In this case expose your application as web component and integrate with any application.

class AdvanceSearch extends HTMLElement {
  connectedCallback() {
    const mountPoint = document.createElement('span');
    this.attachShadow({ mode: 'open' }).appendChild(mountPoint);

    const name = this.getAttribute('name');
    const url = 'https://www.google.com/search?q=' + encodeURIComponent(name);
    ReactDOM.render(<a href={url}>{name}</a>, mountPoint);
  }
}
customElements.define('x-search', AdvanceSearch);

Comments

Popular posts from this blog

React Redux Tutorials: React Redux Data Flow and Redux Lifecycle Methods With Examples

React Redux Data Flow and Redux Lifecycle Methods Overview What is Redux and why do we need Redux Redux is an open source JavaScript library which is designed for maintaining application state. Redux JS is a powerful and popular library nowadays. The command to install Redux library npm install redux --save . Nowadays JavaScript single-page applications are very popular and powerful. As the requirements for single-page applications have become complicated, our code must manage more state than ever before. This state can include server responses and cached data, as well as locally generated data that has not yet been persisted to the server. Front-end state is also increasing in complexity, as we need to manage active routes, selected tab, spinners, pagination controls etc. That's why we need Redux. click here to learn React Redux Architecture, folder structure. Three Principles of Redux: Changes are made with pure functions You write pure reducers to specify

React Redux Application Structure, Architecture and React Folder Structure Best Practices

React Redux Application Structure, Architecture and  React Folder Structure Best Practices: There some questions comes our mind when we are going to create a new react redux application structure from scratch. What folder structure should be followed especially when we are implementing a large react redux application . How to connect react with redux  What should be the naming convention of folder and react js files. What are the best practices of react redux project structure. The structure might be different for each of us but I am sharing the standard react redux application structure which is followed by most of the UI developers in IT industry. High Level React Redux Application Architecture There are many folders and files in above application screen shot, let discuss one by one. The application name is REACTWEBAPP and folders are config, public, script, server, src, reducers, sagas, store and package.json. Config: react redux application configurations

ReactJS Routing And Single Page Application Tutorial

React Router: ReactJS Single Page Application Why do we need React Router Nowadays single page application is the most popular. For making single page application, we need to react router. Single page application is very powerful and provides performance features as well. What is React Router React router is a library, it provides routing feature through which we can redirect from one page to another page. Mainly there are two types of routing. 1. Browser Specific routing: In general or e-commerce web application have browser routing and it helps in search engine optimization. npm command to install routing package npm install react-router --save . --save is used to save the package entry in project specific package.json file. import React from 'react'; import ReactDOM from "react-dom"; import { Router, Route, Link, browserHistory, IndexRoute } from 'react-router'; import Home from './Home'; import About from './About'; import