If you have any questions or feedback, pleasefill out this form
This post is translated by ChatGPT and originally written in Mandarin, so there may be some inaccuracies or mistakes.
React has officially released version 16, and the official blog provides a comprehensive (and visually appealing) overview. This article serves as a condensed note and summary of some details.
1. componentDidCatch(error, info)
One of the most exciting features of React 16 is the introduction of Error Boundaries, which ensure that errors during the lifecycle do not affect the entire component. Previously, if an error occurred during rendering, it would cause the entire component to disappear.
The componentDidCatch
method will only be called if an error occurs in a lifecycle method, so throwing an error in places like the constructor will not be caught by componentDidCatch
.
componentDidCatch
receives two parameters: error
and info
. You can handle errors within componentDidCatch
, implement a fallback UI, or call a third-party service to log the error, among other actions.
class Post extends Component {
constructor() {
throw new Error("oops") // Will not be caught by componentDidCatch
}
componentWillMount() {
this.setState(state => {
throw new Error("oops")
return {}
})
}
}
class App extends Component {
constructor() {
super(props)
this.state = {
post: { content: "" },
}
}
updatePost = () => {
this.setState(state => ({ ...state, post: null }))
}
componentDidCatch(error, info) {
this.setState({ hasError: true })
Logger.warn(error, info)
}
render() {
return (
<div>
<Post post={this.state.post} />
</div>
)
}
}
In addition to the example above, you can also wrap componentDidCatch
using higher-order component techniques, or set up ErrorBoundary
components to handle errors for children uniformly.
2. Text-Only component
Unnecessary <span>
and react-text
nodes have been removed, and you can now directly return strings.
const Text = ({ text }) => {
return "pure string!"
}
class App extends Component {
render() {
return (
<div>
<Text /> // Renders 'pure string', rather than <span>pure string</span>
</div>
)
}
}
*3. ReactDOM.createPortal(component, dom)
createPortal
is another feature I particularly enjoy. It allows you to render components to different DOM nodes within the Component Tree, completely independent of the children, as shown in the structure below.
<div id="app1"></div>
<div id="app2"></div>
class App extends Component {
constructor() {}
render() {
return (
<div>
<h2>Main header</h2>
{ReactDOM.createPortal(<Sidebar />, document.querySelector("#app2"))}
</div>
)
}
}
With ReactDOM.createPortal()
in App
, not only does it improve readability (without needing callbacks or directly manipulating the DOM), but it also allows for operations on nodes outside of the children, making it very convenient for writing components like modals that may require overlays. (Overlays are better handled at the root node level.)
4. Custom Attributes
render() {
return (
<div ui-prefix-scroller='foo'>
</div>
)
};
5. Prevent Update
Returning null
in setState
will not trigger an update (unlike previous versions). If you want to avoid updating a component in the future, you can simply pass null
.
6. SSR Support
For more details, refer to What's new with server-side rendering in React 16. Notably, React 16 SSR now supports streaming, with renderToNodeStream(Component)
returning a stream.
Additionally, the article's author emphasizes:
Please, please, please make sure you always set
NODE_ENV
toproduction
when using React SSR in production!
Conclusion
These are the main changes in React 16. The official blog provides a more detailed introduction.
If you found this article helpful, please consider buying me a coffee ☕ It'll make my ordinary day shine ✨
☕Buy me a coffee