React 18 Alpha has been released, with new features and apis focused on user experience and performance improvements
The installation
npm install react@alpha react-dom@alpha
Copy the code
Root API
- Leacy root API: reactdom.render ()
- New root API: reactdom.createroot ()
The difference
The old root API
import React from 'react';
import ReactDOM from 'react-dom';
const container = document.getElementById('root')
ReactDOM.render(<App />, container);
Copy the code
New Root API (React 18)
import * as ReactDOM from 'react-dom';
import App from 'App';
const container = document.getElementById('app');
// Create a root node
const root = ReactDOM.createRoot(container);
// Initial render: Render elements to the root node
root.render(<App tab="home" />);
// There is no need to pass the container when updating
root.render(<App tab="profile" />);
Copy the code
hydration
Tells function moves before hydrateRootAPI:
import ReactDOM from 'react-dom';
import App from 'App';
const container = document.getElementById('app');
ReactDOM.hydrate(<App tab="home" />, container);
Copy the code
After:
import ReactDOM from 'react-dom';
import App from 'App';
const container = document.getElementById('app');
// Build and render chocolate.
const root = ReactDOM.hydrateRoot(container, <App tab="home" />);
// It can be updated later
root.render(<App tab="profile" />);
Copy the code
render callback
In the old root API, Render accepted a callback
import ReactDOM from 'react-dom';
import App from 'App';
const container = document.getElementById('app');
ReactDOM.render(container, <App tab="home" />.function() {
// called after initial rendering or update
console.log('rendered'.)});Copy the code
New root API
import * as ReactDOM from 'react-dom';
import App from 'App';
const rootElement = document.getElementById('app');
ReactDOM.createRoot(rootElement).render(<App callback={()= > console.log("renderered")} />);
/ / or
ReactDOM.createRoot(rootElement).render(<App />);
requestIdleCallback(callback);
/ / or
ReactDOM.createRoot(rootElement).render(<App />);
setTimeout(callback, 0);
Copy the code
Automatic batching
Batch updates refer to multiple states, not multiple updates of one state.
The difference
Before:
function App() {
const [count, setCount] = useState(0);
const [flag, setFlag] = useState(false);
function handleClick() {
setCount(c= > c + 1);
setFlag(f= >! f);// Two properties are updated, but React only renders once
}
function handleClick2() {
fetchSomething().then(() = > {
// React 17 and before will not be batch updated
setCount(c= > c + 1); // Causes a re-render
setFlag(f= >! f);// Causes a re-render
});
}
return (
<div>
<button onClick={handleClick}>Next</button>
<h1 style={{ color: flag ? "blue" : "black}} ">{count}</h1>
</div>
);
}
Copy the code
Before React 18, only React event handlers were batch updated. Promises, setTimeout, native events, and other events were not batch updated. In Act18, there are batch updates in promises, setTimeout, native events, and other events. After:
function App() {
const [count, setCount] = useState(0);
const [flag, setFlag] = useState(false);
function handleClick() {
fetchSomething().then(() = > {
// React 18 and use the New root API
setCount(c= > c + 1);
setFlag(f= >! f);// only render once
});
}
return (
<div>
<button onClick={handleClick}>Next</button>
<h1 style={{ color: flag ? "blue" : "black}} ">{count}</h1>
</div>
);
}
Copy the code
Don’t want to batch update?
import { flushSync } from 'react-dom';
function handleClick() {
flushSync(() = > {
setCounter(c= > c + 1);
});
React now updates the DOM
flushSync(() = > {
setFlag(f= >! f); });React now updates the DOM
}
Copy the code
startTransition()
In React, if the UPDATED DOM tree is large, ODM comparison takes a long time, which may lead to unresponsive pages and stalling. StartTransition () solves this problem. Take an example: enter text in the input box, and display a list of prompts according to the input text query data.
// Pressing: displays input text
setInputValue(input);
// Not pressing: displays the query result
setSearchQuery(input);
Copy the code
If there are a lot of results at this point, synchronizing the render result list may cause the input box to stall. React 18 prior to React 18 all updates were rendered simultaneously.
// Pressing: display text
setInputValue(input);
/ / state
startTransition(() = > {
// Transition: Displays the result
setSearchQuery(input);
});
Copy the code
Means that the state update of the startTransition flag can be interrupted by a more urgent update. Avoid page lag.
Suspense
<Layout>
<NavBar />
<Sidebar />
<RightPane>
<Post />
<Suspense fallback={<Spinner />} ><Comments />
</Suspense>
</RightPane>
</Layout>
Copy the code
In Suspense/>, React can skip the request for comment data and continue parsing the rest of the HTML. This will not block.
useDeferredValue
Text that does not require urgent display can be delayed for a certain amount of time, reducing the update priority
const deferredValue = useDeferredValue(value, { timeoutMs: 3000 });
Copy the code
The article may have some misunderstanding, please correct it
React 18 All updates to the discussion list