React logo

Technology review – React 16.9

React 16.9 landed in August 08 2019. Bringing with it numerous bug fixes, as well as some new features, including  <React.Profiler> , and a testing utility act()

Tl; dr;

React 16.9 does NOT contain any breaking changes, so we can upgrade from 16.8 safely. It contains a programmatic profiler so developers can measure the performance of the components in specific, and the whole application in general. Introducing a new-ish testing function act(), helping to simulate exactly how React works in a real browser.

Deprecations

Unsafe lifecycles

Major deprecation warnings are introduced in this update. Firstly, deprecated lifecycle methods are now renamed to UNSAFE_…

class MyComponent extends React.Component {
  // previously componentWillMount()
  UNSAFE_componentWillMount() { ... }

  // previously componentWillReceiveProps
  UNSAFE_componentWillReceiveProps() { ... }

  // previously componentWillUpdate()
  UNSAFE_componentWillUpdate() { ... }
}

The old lifecycle methods will be removed in the future updates. For 16.9, they only throw warnings if the code contains these lifecycle methods.

To help with migration, Facebook also introduces a library called react-codemod to help changing these names across your codebase. More details in the official announcement from React team.

Javascript: URLs

Another deprecation is the usage of javascript: URLs

We have been always able to copy and paste the following code into the url bar and see your current browser name. Or you can change it for it to do all sort of things, including exploiting cyber-security vulnerabilities.

javascript: alert(`Hello champion. Your browser is ${window.navigator.platform}`);

In React 16.9, the usage of this syntax will throw a warning and React team plan to have it throwing an error in the future. More details here.

“Factory” components

Previously, we can create a factory component function to create dynamic components based on our needs. This is before having Babel to compile React classes.

const factoryComponent = (type) => {
  return {
    render() {
      return <div>{type}</div>;
    }
  };
};

Now, with such usage, React will throw a warning to notify developers to avoid this pattern. We can alter the code to properly return a function/component class instead.

// factory for functional components
const factoryComponent = (type) => {
  return () => <div>{type}</div>;
};

// factory for component class
const factoryComponent = (type) => {
  return class extends React.Component {
    render() {
      return <div>{type}</div>;
    }
  }
};

New features

Async act()

Finally we can use act() with asynchronous function. Prior to 16.9, it only accepts a normal function.

const asyncFunc = async () => { ... };

// before
it('should do something', (done) => {
  act(() => {
    asyncFunc()
      .then(() => done())
      .catch(err => done(err));
  });
});

// after
it('should do something', () => {
  act(() => asyncFunc());
});

React.Profiler()

Basically it’s a wrapper component to allow a callback function to be executed everytime the underlay components are called.

class App extends React.PureComponent {

  constructor(props) {
    super(props);

    this.state = {
      counter: 1,
    };

    setInterval(() => this.setState({ counter: this.state.counter + 1 }), 1000);
  }

  render() {
    const onRender = () => {
      console.log(arguments);
    };
    
    return (
      <React.Profiler id="application" onRender={onRender}>
        <div className="App">
          {this.state.counter}
        </div>
      </React.Profiler>
    );
  }
}

And we have this in our console.

For more information on Profiler, React team provide a deep down documents here.

Summary

Every React version brings us joy to test and tinker with the new features. React 16.9 is no different. I had fun working with the #bleedingedge. Hopefully I can integrate some of these new features into my work soon.

By Tuan Nguyen

One thought to “Technology review – React 16.9”

Leave a Reply

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