React StrictMode explained

The <React.StrictMode> component is a feature added to React in version 16.3 designed to help you remove old patterns in your React code that will be deprecated in the future.

The component will not render any visible interface, and any red flag in your components will output an error log in the browser console.

To use the StrictMode, you need to wrap your application with <React.StrictMode> component as shown below:

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

You can also exclude any component from the StrictMode by placing them outside of <React.StrictMode> component as follows:

function App() {
  return (
    <div>
      <Header />
      <React.StrictMode>
        <Content />
      </React.StrictMode>
    </div>
  );
}

The <React.StrictMode> component above will check only the <Content> component while ignoring the <Header> component.

Keep in mind that StrictMode will only run on development and will be excluded during React production build. You don’t need to remove or comment the component manually for production.

The pattern that the StrictMode looks for in your code is as follows:

  • Calling on unsafe class component lifecycle methods
  • Using strings for ref attributes in your component
  • Using ReactDOM.findDOMNode() method
  • Using old Context API (Component.contextTypes pattern)
  • Detecting side-effects from your application by calling certain lifecycle methods twice

Let’s break down how these patterns are identified in your code next.

Calling on unsafe class component lifecycle methods

A few class component lifecycle methods have been marked as unsafe to use because they may produce bugs and unintended behavior.

Using these lifecycle methods in your class component will trigger an error log in your browser console:

  • componentWillMount
  • componentWillReceiveProps
  • componentWillUpdate

Keep in mind that the word unsafe here does not refer to application security. It means they are prone to cause bugs with the way future versions of React work internally.

Learn more about why these methods are considered unsafe here

Using strings for ref attributes in your component

In the past, React allows you to use a string as a value of your component’s ref attribute as shown below:

<input 
  ref="textInput" 
  type="text" 
  name="username" />

You can then get a reference to your <input> component using this.refs.textInput.

Overtime, the use of string refs cause some edge cases, so you are recommended to stay away from it in favor of using object refs.

To create an object reference, you can use the React.createRef() method during the constructor() class as shown below:

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

  componentDidMount() {
    this.textInputRef.current.focus();
  }

  render() {
    return <input type="text" ref={this.textInputRef} />;
  }
}

You can learn more about the createRef() method here

Using ReactDOM.findDOMNode() method

ReactDOM provides the findDOMNode() method as a last resort to find your component when all other methods have failed.

The method will travel across the components that have been mounted to the DOM and return the corresponding native browser DOM element:

ReactDOM.findDOMNode(Component);

However, the use of findDOMNode() is now discouraged because it goes against React’s declarative style.

You can also attach the ref attribute to the component you need and avoid using the findDOMNode() method altogether.

Using old Context API pattern

In previous versions, you can access the Context API by using the Component.contextTypes property.

The component that provides context (or the parent component) could create and set context value by using childContextTypes property and getChildContext() method.

For example, suppose you have an app structure as follows:

<App>
  <Content>
    <Button></Button>
  </Content>
</App>

You can send data from <App> component to <Button> component without sending a prop to the <Content> component.

First, create and set the Context API value in <App> component as follows:

class App extends React.Component {
  getChildContext() {
    return {color: "purple"};
  }

  render() {
    return <Content>Hello World</Content>;
  }
}

MessageList.childContextTypes = {
  color: PropTypes.string
};

Next, go into your <Button> component and fetch the context value color using ContextTypes as shown below:

class Button extends React.Component {
  render() {
    return (
      <button style={{background: this.context.color}}>
        {this.props.children}
      </button>
    );
  }
}

Button.contextTypes = {
  color: PropTypes.string
};

However, this pattern has been deprecated in favor of the modern Context API that uses the React.createContext() method that’s more intuitive and easier to understand.

Detecting side-effects from your application

As the development of React continues, the library developers have been making experiments to push the way React works internally.

Future React versions are expected to run concurrently by default, which means that your application will be rendered in pieces, reducing the time required to load your JavaScript code and provides the first meaningful content.

For this reason, the StrictMode will run the following methods in your component twice to ensure that your application produces a consistent result:

  • Class component constructor(), render(), and shouldComponentUpdate() methods
  • Class component static getDerivedStateFromProps method
  • Entier function component body
  • State updater functions (the first argument to setState())
  • Functions passed to useState, useMemo, or useReducer hook

By running the above methods twice in development mode, the StrictMode will help you to catch bugs and undesired results faster.

And that’s how <React.StrictMode> works. For more information, you can visit the official React StrictMode documentation.

Take your skills to the next level ⚡️

I'm sending out an occasional email with the latest tutorials on programming, web development, and statistics. Drop your email in the box below and I'll send new stuff straight into your inbox!

No spam. Unsubscribe anytime.