Vue & React lifecycle method comparison

This was going to be a longer post but I thought this was interesting enough to post now.

React and Vue both have fairly well defined lifecycle events which we can use to successfully navigate the mysteries of the virtual DOM.

So without further ado, let’s get down to the React vs Vue lifecycle events smackdown!

Vue and React fighting in an animated fashion. A caption reads "Bam!"

Vue lifecycle events visualised

The following demo logs out the Vue lifecycle events when a component mounts and updates.

It’s actually a fairly nice API in that everything is consistently named, even if not all of the events are strictly useful.

Vue lifecycle events on codepen

React lifecycle events visualised

React is actually the more esoteric of the two in terms of naming, but actually offers more powerful functionality (such as my particular favourite, shouldComponentUpdate).

Vue lifecycle events on codepen

Component mount compared

The basic workflow for a component is pre-mount → render → mount.

Vue has more events, whereas React is more Javascripty with an actual ES constructor.

React Vue Description
constructor beforeCreate Roughly synonymous with each other. The constructor sets up the React class, whereas Vue handles the class creation for you.
- data Set data. Vue recursively converts these properties into getter/setters to make them “reactive”.
- created Data observation, computed properties, methods, watch/event callbacks have been set up.
- beforeMount Right before the mounting begins: the render function is about to be called for the first time.
getDerivedStateFromProps - Invoked right before calling the render method. It should return an object to update the state, or null to update nothing.
render render The virtual DOM is rendered and inserted into the actual DOM.
componentDidMount mounted The component is now mounted. We can make any direct DOM manipulations at this point.

We can see from our lifecycle that the perfect time to hook into the process is once the component has been mounted (in React’s componentDidMount or Vue’s mounted event).

Component update compared

Component update generally follows a pre-update → render → updated workflow. Easy!

React Vue
getDerivedStateFromProps - Same as when mounting.
shouldComponentUpdate - Let React know if a component’s output is not affected by the current change in state or props. We can use this to prevent React blowing away our changes.
- beforeUpdate Called when data changes, before the DOM is patched.
render render The virtual DOM is rendered and patched into the actual DOM.
getSnapshotBeforeUpdate - Right before the most recently rendered output is committed to the DOM. Lets you save the previous state of the DOM for use after the component has updated.
componentDidUpdate updated After the DOM has been updated

Component unmount compared

When your component is removed from the page, sometimes you need to remove event handlers or clean up after any manual DOM manipulation.

React Vue Description
- deactivated When using Vue keep-alive, the component is removed from the page but not destroyed so that we can load it again later without the overhead of component mount.
- activated The previously deactivated component is reactivated.
componentWillUnmount beforeDestroy When a component is being removed from the DOM
- destroyed The component is completely gone.

Handling errors

This is something I’ve not looked too much into, but it’s possible to catch errors from child components and change the render accordingly.

This would be most useful for a top-level component (above the routes, maybe) to show an “Aw Snap” error message into your app and stop the error bubbling up.

React Vue Description
componentDidCatch
getDerivedStateFromError
errorCaptured An error occurred in a child component.

Conclusion

Each has their own benefits, neither is objectively better or worse. Personally I prefer the Vue naming, but prefer the power of the React API.

After pulling this info together I’m really interested to try out Vue’s keep-alive for render-intensive jobs. It’s a cool feature I didn’t know existed.

I’m also excited to play with component-level error handling, especially for larger apps. It makes a lot of sense to catch errors in the framework rather than waiting for them to bubble up to the global error handler 😅

Anyway, hope this was helpful. I learned something.