Debug
Higher Order Components Wrap other components and throws errors when inner components has error.
1 | // ErrorBoundary.js |
1 | // App.js |
Stateful and Stateless Component
Change in state
and props
will trigger re-rendering of the DOM.
Stateful(Containers)
class XY extends Component
- Access to State
- Lifecycle Hooks
this.state.XY & this.props.XY
- Use only if you need to manage State or access to Lifecycle Hooks
Stateless
const XY = (props) => {...}
- Cannot Access to State
- Do not have Lifecycle Hooks
props.XY
- Use in all other cases
Component Lifecycle
Only available in Stateful Components
Creation of Components
constructor(props)
create component, and instantiate. Always callsuper()
and callprops
if we implementconstructor()
- Do not cause side-effects (re-render the application and reduce performance)
componentWillMount()
won’t use muchrender()
Prepare & Structure your JSX code- Render Child Components
componentDidMount()
Cause Side-Effects. Don’t update state (trigger re-render)
Update (triggered by Parent)
componentWillReceiveProps(nextProps)
Sync State to the updated props. Don’t cause side-effectsshouldComponentUpdate(nextProps, nextState)
May cancel updating process.- Do: Decide whether to continue or not
- Don’t: Cause Side-Effects
componentWillUpdate
- Do: Sync state to props
- Don’t: Cause Side-Effects
render()
Prepare & Structure your JSX code- Update Child Component Props
componentDidUpdate()
- Do: Cause Side-Effects
- Don’t: Update State (trigger re-render)
Update (triggered by Internal Change)
shouldComponentUpdate(nextProps, nextState)
Decide whether to continue or notcomponentWillUpdate()
Sync State to Propsrender()
Prepare and Structure your JSX codeUpdate Child Component Props
componentDidUpdate()
Cause side effects
How react upates the App & the component tree
When the render()
is called, the DOM does not necessarily change.
- Compare Old Virtual DOM and the new re-rendered virtual DOM
- If differences are found, update the different part of the DOM (if
shouldComponentUpdate()
is passed)
setState Correctly
setState
works asynchronously, thus it would be dangerous to directly use it as:
1 | this.setState({ |
Instead, we should use this:
1 | toggleHandler() { |
String props types
npm install --save prop-types
1 | import PropTypes from 'prop-types'; |
Access Elements with ref
Can only be used in the stateful components1
2
3
4
5
6
7
8
9
10componentDidMount() {
this.inputElement.focus();
}
render() {
return (
<input
ref={(inp) => {this.inputElement = imp}} //
>
)
}
1 | // After 16.3 |
Lifecycle Hooks
Creation
From top to bottom is the running sequence of lifecycle hooks
Syntax | DO | DON’T | Other |
---|---|---|---|
constructor(props) |
Set up Initial State | Cause Side-Effects | Default ES6 class Feature |
getDerivedStateFromProps(props,state) |
Sync state | Cause Side-Effects | not used much |
render() |
Prepare & Structure JSX Code | Cause Side-Effects | |
Render Child Component | |||
componentDidMount() |
Cause Side-Effects | Update State synchronisly(can update with HTTP) | Very Important |
Syntax1
2
3static getDerivedStateFromProps(props, state) {
return state;
}
componentWillMount()
will be removed in the future.
Update (prop changes)
props changes are mostly for external data changes (i.e.HTTP request)
Syntax | DO | DON’T | Other |
---|---|---|---|
getDerivedStateFromProps(props,state) |
Sync State to Props | Cause Side-Effects | |
shouldComponentUpdate(nextProps, nextState) |
Decide whether to continue or not | Cause Side-Effects | May cancel updating process |
render() |
Prepare & Structure JSX Code | Cause Side-Effects | |
Update Child Component Props | |||
getSnapshotBeforeUpdate(prevProps, prevState) |
Last-minute DOM ops | Cause Side-Effects | Not used much |
componentDidUpdate() |
Cause Side-Effects | Update State Synchronisly | Beware of infinite loop |
getStapshotBeforeUpdate
Usage: can be used to save some data before the update and then use it later the upate.
1 | getStapshotBeforeUpdate(prevProps, prevState) { |
componentWillReceiveProps
and componentWillUpdate
are removed, and shouldn’t be used.componentWillUnmount
runs right before the component is removed from the DOM.
Lifecycle hooks in Functional Components
useEffect
combines all the componentDidMount()
and componentDidUpdate()
1 | import React, { useEffect } from 'react'; |
Performance
Performance Gains
1 | shouldComponentUpdate(nextProps, nextState) { |
PureComponent has built-in shouldComponentUpdate()
function, so it’s optimized to update the states only if it’s different from the old one. Thus, it can increase the performance in some occasions.
1 | import { PureComponent } from 'react'; |
After React 16.4, the stateless component can use memo
method to achieve similar effects.
1 | export default React.memo(component); // will only update when receives props update |
Improve performance with shouldComponentUpdate()
in class-based components.
1 | shouldComponentUpdate(nextProps, nextState) { |
Improve performance for function-based components with react.memo()
. This uses memoization to optimize the performance. It’s a good idea to wrap functional components that might not need to update with every change in the parent component.
1 | const component = () => {...} |
How React Update the DOM
shouldComponentUpdate()
if true -> call render()
-> compare old Virtual DOM with re-rendered Virtual DOM -> If there are differences -> Update real DOM