Javascript

React.js: Communication between Components with Contexts

March 25th, 2015 | By José Magalhães | 3 min read

Communication between components with contexts is an interesting React.js feature, and we explore this option.

Since React v0.12, there has been a new yet undocumented feature that opens up new possibilities for communicating between components. We are talking about contexts in the React.js library for web and native user interfaces. This novelty is still changing, but it’s already being used in projects.

What is a context in React.js?


In brief, a context is an object implicitly passed from a component to its children. So, by using contexts, you don’t have to explicitly pass around a whole bunch of props to pass some contextual data. This was one of the not-so-elegant parts of React that went away when contexts were introduced.

Apart from the missing official documentation, it is a challenge to find accurate literature that sheds some light on how React contexts work. We spent some time understanding its inner workings and using it here at JScrambler, so we thought to contribute with this blog post.

We will show how to code a toggle that changes the context of the parent and a panel that changes its content given a different context.

Parent Component

var React = require('react');

var DummyWrapper = require('./dummy-wrapper');
var ItemToggle = require('./item-toggle');

var Parent = React.createClass({
    getInitialState: function() {
        return {}
    },
    childContextTypes: {
        activeItem: React.PropTypes.any
    },
    getChildContext: function() {
        return {
            activeItem: this.state.activeItem
        };
    },
    setActiveItem: function(item) {
        this.setState({
            activeItem: item
        });
    },
    render: function() {
        return ( < div >
            < ItemToggle setActiveItem = {
                this.setActiveItem
            }
            /> < DummyWrapper / >
            < /div>
        );
    }
});

module.exports = Parent;

childContextTypes is useful during development because it validates the schema against the object returned from getChildContext. While in production, this step is bypassed.

Here, we render the ItemToggle, while passing down @setActiveItem as a prop to allow the child to change the parent state (and context).

We also render a DummyWrapper that will have a child that depends on the Parent component.

Item Toggle Component

var React = require('react');

var ItemToggle = React.createClass({
    onClick: function(type) {
        var item;

        switch (type) {
            case 'A':
                item = "Item A";
                break;
            case 'B':
                item = "Item B";
                break;
            default:
                throw new Error('Unimplemented type');
        }

        this.props.setActiveItem(item);
    },
    render: function() {
        return ( < div > Select an Item:
            < ul >
            < li onClick = {
                this.onClick.bind(this, 'A')
            } > Item A < li onClick = {
                this.onClick.bind(this, 'B')
            } > Item B < /ul> < /div>
        );
    }
});

module.exports = ItemToggle;

Here we receive a prop setActiveItem from the parent that allows us to set the React component that is going to be instanced and set in the parent context.

To keep the simple example, Item A and Item B are just strings. Of course, you could easily replace them with React components.

Dummy Wrapper Component

var React = require('react');

var ActiveItemPanel = require('./active-item-panel');

var DummyWrapper = React.createClass({
    render: function() {
        return <ActiveItemPanel / > ;
    }
});

This component shows how ActiveItemPanel can access the context of the Parent component, even though they are not directly related.

Active Item Panel Component

var React = require('react')

var ActiveItemPanel = React.createClass({
    contextTypes: {
        activeItem: React.PropTypes.any
    },
    render: function() {
        return ( < div >
            Active Item: {
                this.context.activeItem
            } < /div>
        );
    }
});

module.exports = ItemPanel;

Here, we're defining the context types that we receive through contextTypes. Besides this, we render @context.activeItem inside the component.

As you can see, we didn’t even pass any props to this component. The context lies there without effort.

Conclusions about React's new feature


The API allows owner-owned communication, but it has already been announced that React’s v0.14 release context will work on the parent-child relationship, which allows even more options than the former.

Though the API may change, this is extremely powerful and avoids a lot of explicit props being passed from parents to children. At the same time, your component will be a little more coupled to where it’s being used, which in some scenarios may not be what you’re looking for.

If you are developing React applications with sensitive logic, protect them against code theft and reverse engineering.

Jscrambler

The leader in client-side Web security. With Jscrambler, JavaScript applications become self-defensive and capable of detecting and blocking client-side attacks like Magecart.

View All Articles

Must read next

Web Security

Protecting Your React.js Source Code with Jscrambler

In this step-by-step guide, you'll learn how to protect your React.js application with Jscrambler to prevent code theft and reverse-engineering.

February 1, 2019 | By Jscrambler | 6 min read

Web Development

Easy Custom Webpack Setup for React.js Applications

Webpack is currently the most popular code bundler but can be quite confusing. In this guide, we present a custom configuration for React.js apps.

July 23, 2019 | By Lamin Sanneh | 10 min read

Section Divider