Challenges with React 16 upgrades
We have been using React for 3 years at Recruiterbox. We faced a lot of challenges during the update of react 16 mainly due to legacy code and the number of files (3000+) we have.
React 16 upgrade overview:
- 46 Pull-request
- 450 commits
- 36000 line changes
- ~2 months(with feature development in parallel)
How we did it
- Upgrade to v15.6.0 (we were using v15.4.0)
- Remove usage of React.createClass
We used the codemod to update all our files. The major friction here was the eslint issues on the our old files.
Codemod https://github.com/reactjs/react-codemod#explanation-of-the-new-es2015-class-transform-with-property-initializers - Remove usage of React.PropTypes
Codemod https://github.com/reactjs/react-codemod#react-proptypes-to-prop-types - Remove usage of react-addons-css-transition-group
Due to discontinuing support for React Addons, we had to replace the usage with react-transition-group.
https://reactjs.org/blog/2017/04/07/react-v15.5.0.html#discontinuing-support-for-react-addons - Remove usage of react-addons-test-utils
We have ~2000 tests for our react code base.
1) Replace import TestUtils from ‘react-addons-test-utils’; to import TestUtils from ‘react-dom/test-utils’;
2) Replace import { createRenderer } from ‘react-addons-test-utils’; to import { createRenderer } from ‘react-test-renderer/shallow’;
3) If you are using skin-deep or other libs using react-addons-test-utils, you need to ignore it by adding the webpack.IgnorePlugin(/ReactContext|react-addons-test-utils/)
https://reactjs.org/blog/2017/04/07/react-v15.5.0.html#react-test-utils - Portal
ReactDOM.unstable_renderSubtreeIntoContainer to ReactDOM.createPortal - Major Eslint error we had to fix.
Ref string deprecations, replace all the ref string to functional refs - Upgrade supporting libraries
a) skin-deep
b) react-bootstrap
c) react-bootstrap-table
d) react-router 4 from beta
Issues we faced:
1. Portal
Events now bubble up to the parent component
Even though a portal can be anywhere in the DOM tree, it behaves like a normal React child in every other way. Features like context work exactly the same regardless of whether the child is a portal, as the portal still exists in the React tree regardless of position in the DOM tree. https://github.com/facebook/react/issues/11387
2. Change in behaviour of componentWillUnmount lifecycle method
When replacing <A /> with <B />, B.componentWillMount now always happens before A.componentWillUnmount. Previously, A.componentWillUnmount could have fired first in some cases.
https://reactjs.org/blog/2017/09/26/react-v16.0.html
What we love:
componentDidCatch: We love this api! When working with rich UI, interaction this api helps us to contain the error. https://reactjs.org/blog/2017/07/26/error-handling-in-react-16.html
What we learnt:
- Update the libraries to the latest version as soon as possible.
- Create a wrapper component for all the third-party libraries so that we can easily make modification at one place.