Austin Roy Omondi Live long and prosper 👌

What to expect in React v17

4 min read 1134

React Fiber(React v16) is awesome and has taken some significant steps towards improving the developer experience as well as the quality of applications built with React. In this post, we will look at how React 17 looks to build on React v16.

Why asynchronous rendering?

With a strong focus on asynchronous rendering, React 17 looks to create an environment for developers to build efficient applications easily by making it possible to minimize the impact of computing and network speeds on the user experience.

To achieve this, there will inevitably be some shift in the way React apps are written through the introduction of some new features and deprecation of some previous ones.

Here are the changes we can expect:

  • Introduction of new lifecycle methods
  • Time slicing
  • Suspense

Let’s look at them one by one.

New lifecycle methods

Replacing the deprecated lifecycle methods are two new lifecycle methods, getDerivedStateFromPropsand getSnapShotBeforeUpdate.

These are essential to keep in mind if you are preparing to migrate your application to React 17. A great starting point is replacing the unsafe methods with these new lifecycle methods. For instance, componentWillUpdate can be replaced by using getDerivedStateFromProps in conjunction with shouldComponentUpdate, componentWillMount should be removed altogether for async rendering.

Here’s a diagram of what the component lifecycle will look like after React v16.4 with the unsafe methods removed.

getDerivedStateFromProps

This lifecycle method replaces componentWillReceiveProps and componentWillUpdate and will be called after a component is created and when it received new props. It returns an object to update state when props change or null when there is no change in state.

state = { cachedSomeProp: null };

static getDerivedStateFromProps(nextProps, prevState) {
  // do things with nextProps.someProp and prevState.cachedSomeProp
  return {
    cachedSomeProp: nextProps.someProp,
    ..
  };
}

However, keep in mind that this lifecycle method is only meant to be used in cases where a component needs to update its local state following a change in props. Unnecessary use of this method may introduce some bugs such as unconditionally copying props to state and erasing state when props change as was the case with componentWillReceiveProps.

getSnapshotBeforeUpdate

This handles component updates and will effectively replace componentWillUpdate and works with componentDidUpdate. It is called before any DOM updates and returns a value that is passed to componentDidUpdatewhich then handles the changes:

class ScrollingList extends React.Component {
  listRef = null;

  getSnapshotBeforeUpdate(prevProps, prevState) {
    // Are we adding new items to the list?
    // Capture the scroll position so we can adjust scroll later.
    if (prevProps.list.length < this.props.list.length) {
      return (
        this.listRef.scrollHeight - this.listRef.scrollTop
      );
    }
    return null;
  }

  componentDidUpdate(prevProps, prevState, snapshot) {
    // If we have a snapshot value, we've just added new items.
    // Adjust scroll so these new items don't push the old ones out of view.
    // (snapshot here is the value returned from getSnapshotBeforeUpdate)
    if (snapshot !== null) {
      this.listRef.scrollTop =
        this.listRef.scrollHeight - snapshot;
    }
  }

  render() {
    return (
      <div ref={this.setListRef}>
        {/* ...contents... */}
      </div>
    );
  }

  setListRef = ref => {
    this.listRef = ref;
  };
}

Time slicing

Time slicing is the biggest update to React that looks to improve user experience. It aims to make sites more friendly by allowing prioritized rendering of elements. So high priority updates aren’t blocked because of rendering low priority updates.

Dan Abramov likened this to version control at JSConf Iceland 2018. Where work is split into branches and the work of each branch is merged to master once complete. Similarly, with time slice, elements can be rendered separately allowing the app to have ready elements rendered and a placeholder for elements yet to be rendered.

A good example is a case where we are fetching users’ details. The user avatar and name will display and their bio comes in later. Time slice will allow us to display the ready details(name and avatar) and have a placeholder while the bio is fetched. Once the bio is ready it renders and the final state is as expected. This enhances the responsiveness of the app on slower devices and networks and also means the rest of the app can still be used while a certain element is still rendering.

How is this achieved? Through a new API called Suspense that was introduced in React 16.6.

Suspense

Suspense is responsible for rendering the fallback UI(placeholder) while state updates are being prepared. It holds back rendering of the final UI until these updates are ready, rendering a placeholder of your choice in the meantime. This is where you would place your spinner if that’s what you plan to use to indicate a loading state.

This provides a great alternative to conditional rendering to handling data loading. You can also set a time limit and if the data loads within this time the fallback UI will not be rendered in concurrent mode. Awesome, right? Even better, Suspense was introduced in React 16.6, so Suspense is ready to use right now.

Here’s a simple example of Suspense in use:

const DataComponent = React.lazy(() => import('./DataComponent'));

function MySuspenseComponent(){
  return (
    <Suspense fallback={<Spinner />}>
      <DataComponnent/>
    <Suspense>
    )
}

In the above example, Suspense is used in conjunction with lazy() which lazy loads the DataComponent, while the component is loading, a spinner will display and our component only shows up after loading is complete. We can also do this using other async operations such as API calls.

Also expected with React 17 is a stable version of the react-cache library which will help expand on the functionality of Suspense and allow the use of async operations with synchronous operations. Here’s what react-cache may look like:

const getInfo = () => fetch("https://myApi.apiexample").then(res => res.json())

const ApiResource = createResource(getInfo)

const SayHello = () => {
  const data = ApiResource.read()

  return <div>Hi {data.name}</div>
}

const App = () => (
  <Suspense fallback={<Spinner />}>
    <SayHello />
  </Suspense>
)

The react-cache may also be used with time slicing to load data in the background as a low priority update, a good example is when displaying data as tabs, this makes the data instantly available when switching between tabs. Andrew Clark gave a great demo of such as a use case at React Conf 2018, check it out below:

Concurrent Rendering in React 

Conclusion

React 17 is a major release with several reasons for React developers to get excited. Not only does it provide some amazing, new features that will redefine how React applications are built, but it also expands on recently introduced features such as Hooks with incremental changes that allow developers to make better use of them. This will lead to better applications and a better experience building them. It is exciting to see what else the future holds for React.

You may also want to check out Dan Abramov’s talk at JS Conf 2018 which I referred to when compiling this article.

 

Plug: , a DVR for web apps

LogRocket is a frontend application monitoring solution that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.

In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page apps.

.
Austin Roy Omondi Live long and prosper 👌

Leave a Reply