Â
And how does it affect our work?
New Core Algorithm
Error Boundary
Fragments
Portals
Better SSR
Other new feature
Stack reconciliation VS Fiber reconciliation
The "diffing" process of virtual DOM in React is called reconciliation
Stack VS Fiber
Cooperative scheduling
To split the rendering work into chunks and spread out over multiple frames
The commit phase is usually very fast, but rendering can be slow. For this reason, the upcoming async mode (which is not enabled by default yet) breaks the rendering work into pieces, pausing and resuming the work to avoid blocking the browser
The life cycle methods may not fire in the same order you expected.
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
componentDidCatch(error, info) {
this.setState({ hasError: true });
console.log(error, info);
}
render() {
if (this.state.hasError) {
// You can render any custom fallback UI
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
const entry =
document.getElementById("root");
ReactDOM.render(
<ErrorBoundary>
<MyWidget></MyWidget>
</ErrorBoundary>,
entry
);
<div id="root">
<!-- This div's content will
be managed by React. -->
</div>
const MyWidget = () => {
return <h2>My Widget</h2>;
}
React 15.1.0: https://codepen.io/melonq/pen/WzWpmM​
Â
React 16.3.1: https://codepen.io/melonq/pen/WzWpgd
renderTitles() {
return (
<div>
<h2>MainTitle</h2>
<h3>SubTitle</h3>
</div>
);
}
renderItems() {
return (
<div>
{this.props.items.map((item, index) =>
<ItemElement data={item} key={index} />)
}
</div>
);
}
renderChildren() {
return (
<div>{this.props.children}</div>
);
}
render() {
// Don't forget the keys
return [
<li key="A">First item</li>,
<li key="B">Second item</li>,
<li key="C">Third item</li>,
];
}
render() {
// No need for comma and keys
return (
<React.Fragment>
<li>First item</li>
<li>Second item</li>
<li>Third item</li>
</React.Fragment>
);
}
render() {
return (
<>
Some text.
<h2>A heading</h2>
More text.
<h2>Another heading</h2>
Even more text.
</>
);
}
Portals provide a first-class way to render children into a DOM node that exists outside the DOM hierarchy of the parent component.
// using Express
import { renderToString } from "react-dom/server"
import MyPage from "./MyPage"
app.get("/", (req, res) => {
res.write(renderToString(<MyPage/>));
res.end();
});
import { render } from "react-dom"
import MyPage from "./MyPage"
const rootDom = document.getElementById("content");
render(<MyPage/>, rootDom);
If you’re reviving server-rendered HTML, use ReactDOM.hydrate instead of ReactDOM.render. Keep using ReactDOM.render if you’re just doing client-side rendering.
customCallback(newCount) {
if (newCount !== 0) {
this.setState((prevState, props) => {
return { count: prevState.count + newCount }
});
}
}
customCallback(newCount) {
this.setState((prevState, props) => {
return (newCount !== 0) ? { count: prevState + 1 } : null;
});
}
<div whatever-you-like="anyData">123</div>
// Yes, please
<div tabIndex="-1" />
// Warning: Invalid DOM property `tabindex`.
// Did you mean `tabIndex`?
<div tabindex="-1" />
class AutoFocusTextInput extends React.Component {
constructor(props) {
super(props);
this.textInput = React.createRef();
}
componentDidMount() {
this.textInput.current.focusTextInput();
}
render() {
return (
<CustomTextInput ref={this.textInput} />
);
}
}
const Context = React.createContext();
render() {
return (
<Context.Provider value={this.state.contextValue}>
{this.props.children}
</Context.Provider>
);
}
render() {
return (
<Context.Consumer>
{context => <Child context={context} />}
</Context.Consumer>
)
}
That amounts to a combined 32% size decrease compared to the previous version (30% post-gzip).