A note on the evolution of important versions of popular front-end libraries/frameworks.
- package.json:"type" field(v12.17.0)
- ESM: Top-Level Await(v14.8.0)
- package.json:"exports" & "imports" patterns - replace
"main"
field(v12.20.0, v14.13.0) node:
protocol imports(v14.18.0, v16.0.0)- fs/promises support(v14.0.0, via
require('fs').promises
from v10.1.0)
ReactDOM.render
is no longer supported in React 18.
// Before
import { render } from 'react-dom';
render(<App tab="home" />, document.getElementById('app'));
// After
import { createRoot } from 'react-dom/client';
const root = createRoot(document.getElementById('app')); // createRoot(document.getElementById('app')!) if you use TypeScript
root.render(<App tab="home" />);
- changed
unmountComponentAtNode
toroot.unmount
.
// Before
unmountComponentAtNode(container);
// After
root.unmount();
- removed the
callback
from render.
// Before
const container = document.getElementById('app');
render(<App tab="home" />, container, () => {
console.log('rendered');
});
// After
function AppWithCallbackAfterRender() {
useEffect(() => {
console.log('rendered');
});
return <App tab="home" />
}
const root = createRoot(document.getElementById('app'));
root.render(<AppWithCallbackAfterRender />);
- Finally, if your app uses server-side rendering with hydration, upgrade
hydrate
tohydrateRoot
.
// Before
import { hydrate } from 'react-dom';
hydrate(<App tab="home" />, document.getElementById('app'));
// After
import { hydrateRoot } from 'react-dom/client';
const container = ;
const root = hydrateRoot(
document.getElementById('app'),
<App tab="home" />
);
// Unlike with `createRoot`, you don't need a separate root.render() call here.
- React Hooks
- Basic Hooks:
useState
,useEffect
,useContext
- Additional Hooks:
useReducer
,useCallback
,useMemo
,useRef
,useImperativeHandler
,useLayoutEffect
,useDebugValue
,useDeferredValue
,useTransition
,useId
- Library Hooks:
useSyncExternalStore
,useInsertionEffect
- Basic Hooks:
WARNING:This version was released in November 2014, but is still in beta as of today.
remove:
app.del - use
app.delete`req.acceptsCharset
- usereq.acceptsCharsets
req.acceptsEncoding
- usereq.acceptsEncodings
req.acceptsLanguage
- usereq.acceptsLanguages
res.json(obj, status)
signature - useres.json(status, obj)
res.jsonp(obj, status)
signature - useres.jsonp(status, obj)
res.send(body, status)
signature - useres.send(status, body)
res.send(status)
signature - useres.sendStatus(status)
res.sendfile
- useres.sendFile
insteadexpress.query
middleware
change:
req.host
now returns host (hostname:port
) - usereq.hostname
for only hostnamereq.query
is now a getter instead of a plain property
add:
app.router
is a reference to the base router
- Add
express.raw
to parse bodies intoBuffer
- Add
express.text
to parse bodies into string
- Add
express.json
andexpress.urlencoded
to parse bodies
- Add
next("router")
to exit from router