React 17 brought several changes that, while not introducing many new features, laid the groundwork for future improvements. This guide will walk you through the process of upgrading your React application from version 16 to 17, covering package updates, testing modifications, and common issues you might encounter.
Before diving into the upgrade process, it's worth mentioning the React Native Upgrade Helper:
This tool can provide valuable insights into the changes required for your specific project.
The first step in the upgrade process is to update your package.json file with the new versions of React and related packages.
- "react": "^16.9.0",
+ "react": "^17.0.2",
- "react-dom": "^16.9.0",
+ "react-dom": "^17.0.2",
- "react-scripts": "^3.2.0",
+ "react-scripts": "^5.0.1",
- "jest-fetch-mock": "^2.1.1",
+ "jest-fetch-mock": "^3.0.0",
+ "@babel/plugin-proposal-private-property-in-object": "^7.21.11",
- "enzyme-adapter-react-16": "^1.14.0",
+ "@wojtekmaj/enzyme-adapter-react-17": "^0.4.1",
- "enzyme": "^3.10.0",
+ "enzyme": "^3.11.0",After updating these dependencies, run npm install or yarn install to install the new versions.
In your test files, replace beforeAll with beforeEach to ensure a fresh setup for each test:
describe('index edge', () => {
- beforeAll(() => {
+ beforeEach(() => {The behavior of jest.spyOn has changed. You now need to explicitly mock the implementation:
- jest.spyOn(_, 'shuffle') # call original but not with 27
+ jest.spyOn(_, 'shuffle').mockImplementation((items) => {
+ return items.reverse()
+ })To prevent issues with _.once across multiple tests, mock it in your test setup:
+import _ from 'underscore';
+
+jest.mock('underscore', () => ({
+ ...jest.requireActual('underscore'),
+ once: jest.fn(fn => fn) // Replace _.once with a passthrough function
+}));Update your setupTests.js file:
# setupTests.js
-import fetchMock from 'jest-fetch-mock'
+import { enableFetchMocks } from 'jest-fetch-mock'
-global.fetch = fetchMock
+enableFetchMocks()When mocking responses, use doMock():
beforeEach((done) => {
- fetch.mockResponseOnce(response)
+ fetch.doMock().mockResponseOnce(response)
_request(dispatch).then(done)
})Add the following rules to your .eslintrc file:
{
"rules": {
"import/no-anonymous-default-export": ["error", {
"allowArray": false,
"allowArrowFunction": false,
"allowAnonymousClass": false,
"allowAnonymousFunction": false,
"allowCallExpression": false,
"allowNew": false,
"allowLiteral": false,
"allowObject": true
}]
}
}To automatically fix ESLint issues, you can use this command:
npx eslint --fix --ext .js,.jsx src|grep .js> files; vim `cat files|sort|tr '\n' ' '`Replace anonymous default exports with named exports:
-export default {
+const actions = {
get: getConfiguration,
}
+
+export default actionsClean up your imports by removing unused ones:
-import { CORRECT, INCORRECT } from '../../../../../constants'
+import { CORRECT } from '../../../../../constants'Upgrading from React 16 to 17 involves several steps, from updating dependencies to modifying your test setup and addressing ESLint warnings. While the process may seem daunting, following this guide should help you navigate the upgrade smoothly. Remember to thoroughly test your application after the upgrade to ensure everything works as expected.
For more detailed information on the changes in React 17, refer to the official React 17 release notes.