Advanced React Concepts that You need to Know

Share this Content

So, you want to know the advanced react concepts. Well, I’ll suggest you read the core concepts first and then come to this article.

React has been designed from the start for gradual adoption, and you can use as little or as much React as you need. Whether you want to get a quick start with React or dive deeper into some advanced concepts, this blog is for you.

In this blog, we will cover:

Advanced React concepts:

  1. Render Props
  2. Higher-Order Components
  3. Context
  4. Portals

React Render Props:

React has a number of powerful features, one of which is the ability to render props.

Render props are a way of passing props to a component without having to use the component's own props. Instead, the component just renders the prop that is passed to it.

This can be useful for a number of reasons. For example, if you want to use a component that doesn’t have any props of its own, you can just render the props that you need. This can also be useful for making reusable components.

Another benefit of render props is that they can make your code more readable. If you have a lot of props that you need to pass to a component, it can be hard to keep track of them all. With render props, you can just render the props that you need, which can make your code easier to read.

There are a few ways to use render props. One way is to use a function as a prop. This function will be called with the props that you pass to it.

Another way to use render props is to use a React component as a prop. This component will be passed the props that you pass to it.

You can also use a string as a prop. This string will be used as the name of the prop that you pass to the component.

If you want to use a prop that is not passed to the component, you can use the special render function. This function will be called with all of the props that you pass to the component.

The render function is a way of making sure that the component always has the props that you need. It can be used to make sure that the component always has the same props, or to make sure that the component has a certain prop.

There are a few things to keep in mind when using render props.

  1. First, you need to make sure that the props that you pass to the component are always valid. If you pass invalid props, the component will not render.
  2. Second, you need to make sure that the props that you pass to the component are unique. If you pass the same prop to two different components, the second component will not render.
  3. Third, you need to make sure that the props that you pass to the component are in the correct order. The order of the props is important because it determines the order in which the props are passed to the component.
  4. Fourth, you need to make sure that the props that you pass to the component are the same type. If you pass a prop that is not the same type as the other props, the component will not render.
  5. Finally, you need to make sure that the props that you pass to the component are in the correct format. The format of the props is important because it determines how the component will render the props.

Render props are a way of sharing code between React components. A component with a render prop takes a function that returns a React element and calls it instead of rendering its own children.

For example, let’s say you have a component that fetches data from an API and passes it down to its children as a prop. You could use a render prop to render a component that displays the data:

class DataProvider extends React.Component {
  state = {
    data: []
  };

fetchData() {
  // Fetch data from API
}

componentDidMount() {
  this.fetchData();
}

render() {
  return (
    <Table data={this.state.data} />
  );
}
}

class Table extends React.Component {
  render() {
    const { data } = this.props;

return (
  <table>
    // Render data in a table
  </table>
);
  }
}

In this example, the component is responsible for fetching the data, while the element is responsible for rendering it. This separation of concerns makes it easier to reason about your code and reuse components.

React Higher-Order Components:

Higher-order components (HOC) are a powerful tool that enables you to reuse code and logic and encapsulate them in a self-contained unit.

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

React higher-order components are a great way to DRY up your code, and they can also make it easier to reason about your code and understand what’s going on.

There are a few things to keep in mind when using higher-order components. First, you should not use a HOC to simply wrap a component in another component – that’s not what they’re for. Second, a HOC should not mutate the original component – it should return a new, enhanced component. Third, a HOC should not access the internals of the original component – it should only take the component as a parameter and return a new, enhanced component.

With that said, let’s look at a few examples of higher-order components.

One common use case for higher-order components is to encapsulate common behaviour. For example, let’s say you have a component that needs to make an API call. You could create a higher-order component that takes care of making the API call, and then pass the data to the original component.

Another common use case for higher-order components is to abstract away states. For example, let’s say you have a component that needs to keep track of a boolean value. You could create a higher-order component that takes care of the state management, and then pass the boolean value to the original component.

Higher order components can also be used to mixin behaviour. For example, let’s say you have a component that needs to use a certain mixin. You could create a higher-order component that takes care of adding the mixin and then pass the component to the original component.

Finally, higher-order components can be used to render a component. For example, let’s say you have a component that needs to be rendered. You could create a higher-order component that takes care of the rendering, and then pass the component to the original component.

React higher-order components are a powerful tool that can help you DRY up your code, and make it easier to reason about your code and understand what’s going on. Just keep in mind the three rules of thumb: don’t use a HOC to simply wrap a component in another component, don’t mutate the original component, and don’t access the internals of the original component. If you follow those rules, you’ll be well on your way to writing clean, reusable code.


HOCs are used for two main purposes:

  1. To share common functionality between components

For example, you could use a HOC to add a loading indicator to a component:

const withLoadingIndicator = (Component) => {
  return class WithLoadingIndicator extends React.Component {
    render() {
      const { isLoading, ...props } = this.props;

return isLoading ? <LoadingIndicator /> : <Component {...props} />;
    }
  };
};

class MyComponent extends React.Component {
  // ...
}
export default withLoadingIndicator(MyComponent);

2. To render a component in a different way

For example, you could use a HOC to wrap a component in a <div>:

const withDiv = (Component) => {
  return class WithDiv extends React.Component {
    render() {
      return (
        <div>
          <Component {...this.props} />
        </div>
      );
    }
  };
};

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

export default withDiv(MyComponent);

React Context:

React Context provides a way to pass data through the component tree without having to pass props down manually at every level.

In a typical React application, data is passed top-down (parent to child) via props, but this can be cumbersome for certain types of props (e.g. locale preference, UI theme) that are required by many components within an application.

Context provides a way to share these types of props between components without having to explicitly pass them down the tree.

Creating a Context

React Context is created using the React.createContext() method.

This method takes a defaultValue argument, which is used when a component does not have a matching Provider above it in the tree.

Once a Context object is created, it can be used by React components in two ways:

Context.Provider

Context.Consumer

Context.Provider

Context.Provider is used to set the value of a Context object.

Subscribe to Tech Break

It accepts a value prop which is used to set the value of the Context object.

Context.Provider can be used inside a React component to provide a Context object to its child components:

import React from 'react';

const MyContext = React.createContext();

class MyProvider extends React.Component {
  state = {
    name: 'John',
  };
  render() {
    return (
      <MyContext.Provider value={this.state.name}>
        {this.props.children}
      </MyContext.Provider>
    );
  }
}

export default MyProvider;

In the example above, the MyProvider component contains a state object with a name property.

The MyProvider component renders a Context.Provider element and passes the value of this.state.name as the value prop.

The MyProvider component then renders its child components.

Context.Consumer

Context.Consumer is used to consume the value of a Context object.

It accepts a function as a child, which is invoked with the value of the Context object.

The function passed to Context.Consumer should return a React element.

Context.Consumer can be used inside a React component to consume the value of a Context object:

import React from 'react';

const MyContext = React.createContext();

function Child() {
  return (
    <MyContext.Consumer>
      {name => <p>Hello, {name}!</p>}
    </MyContext.Consumer>
  );
}

export default Child;

In the example above, the Child component renders a Context.Consumer element.

The function passed as a child to Context.Consumer is invoked with the value of the MyContext object.

The value of MyContext is the name property from the state object in the MyProvider component.

The function passed to Context.Consumer returns a React element which displays the value of the MyContext object (i.e. Hello, John!).

Updating Context

The value of a Context object can be updated by re-rendering the Context.Provider component with a new value prop.

When a Context.Provider component is re-rendered, and the new value prop is used to update the value of the Context object.

All Context.Consumer components that are descendants of the Context.Provider component will re-render with the new value.

In the example below, the value of the MyContext object is updated when the button is clicked:

import React from 'react';

const MyContext = React.createContext();

class MyProvider extends React.Component {
  state = {
    name: 'John',
  };
  render() {
    return (
      <MyContext.Provider value={this.state.name}>
        {this.props.children}
      </MyContext.Provider>
    );
  }
}
function Child() {
  return (
    <MyContext.Consumer>
      {name => <p>Hello, {name}!</p>}
    </MyContext.Consumer>
  );
}

class App extends React.Component {
  render() {
    return (
      <MyProvider>
        <Child />
      </MyProvider>
    );
  }
}

export default App;


In the example above, the App component renders a MyProvider component.

The MyProvider component contains a state object with a name property.

The MyProvider component renders a Context.Provider element and passes the value this.state.name as the value prop.

The MyProvider component then renders the Child component.

The Child component renders a Context.Consumer element.

The function passed as a child to Context.Consumer is invoked with the value of the MyContext object.

The value of MyContext is the name property from the state object in the MyProvider component.

The function passed to Context.Consumer returns a React element which displays the value of the MyContext object (i.e. Hello, John!).

When the button is clicked, the MyProvider component is re-rendered with a new value for the name property in its state object.

This updates the value of the MyContext object, which causes the Child component to re-render.

The Child component now displays the new value of the MyContext object (i.e. Hello, world!).


Context provides a way to pass data through the component tree without having to pass props down manually at every level.

For example, let’s say you have a component that sets the theme for the application. You could use context to pass the theme down to all the child components:

class ThemeProvider extends React.Component {
  static childContextTypes = {
    theme: PropTypes.object
  };

getChildContext() {
  return {
    theme: this.props.theme
  };
}

render() {
  return this.props.children;
}
}

class MyComponent extends React.Component {
  static contextTypes = {
    theme: PropTypes.object
  };

render() {
  const { theme } = this.context;

return <div style={{ backgroundColor: theme.backgroundColor }}>Hello!</div>;
}
}

React Portals:

React portals are a way to render children into a DOM node that exists outside the DOM hierarchy of the parent component. This is useful for modals, tooltips, or any other content that should appear above everything else in the document.

Portals are first-class citizens in React. They have full support for event handling, nesting, and lifecycle methods.

One advantage of React portals is that they allow you to render content into a different part of the DOM without having to worry about the nesting structure of your components.

Another advantage of React portals is that they keep the React hierarchy intact. This means that you can use the React DevTools to inspect the portal content just like any other React component.

Portals are a great way to render modals, tooltips, or any other content that needs to be above everything else in the document.

For example, let’s say you have a component that renders its children into a DOM node with the id “modal”:

class Modal extends React.Component {
  constructor(props) {
    super(props);
    this.el = document.createElement('div');
  }

componentDidMount() {
  document.getElementById('modal').appendChild(this.el);
}

componentWillUnmount() {
  document.getElementById('modal').removeChild(this.el);
}

render() {
  return ReactDOM.createPortal(this.props.children, this.el);
}
}

ReactDOM.render(
  <Modal>
    <div>Hello!</div>
  </Modal>,
  document.getElementById('root')
);

That’s all for this blog, I hope you’ll get the advanced concepts from this article. If you’ve any further questions, feel free to ask that in the comment section. I’ll be thrilled to answer that, or if that needs to be explained, I’ll make another blog on that.

Share this Content
Snehasish Konger
Snehasish Konger

Snehasish Konger is the founder of Scientyfic World. Besides that, he is doing blogging for the past 4 years and has written 400+ blogs on several platforms. He is also a front-end developer and a sketch artist.

Articles: 192

Newsletter Updates

Join our email-newsletter to get more insights

Leave a Reply

Your email address will not be published. Required fields are marked *