Dumb (stateless) and Smart components
Dumb:
import React from 'react';
export default (props = {}) => (
<View/>
)
Smart
export default class extends Component {
state = {}
shouldComponentUpdate(nextProps, nextState){
if (this.props.shuldChildUpdate === nextProps.shuldChildUpdate) {
return false;
}
return true;
}
render = () => {
const { children } = this.props;
return (
<div>{children}</div>
)
}
}
componentShouldUpdate working as expected while in reality asking how to have the child update when the parent does not
Pure
export default class extends PureComponent {
state = {}
// smart shouldComponentUpdate included
render = () => {
const { immutable } = this.state;
return (
<div>{immutable}</div>
)
}
}
Lifecycle
export default class extends Component {
state = {}
constructor()
// depricated componentWillMount = () => {}
// depricated componentWillReceiveProps = (nextProps) => {}
static getDerivedStateFromProps = (props, state) => {}
shouldComponentUpdate = (nextProps, nextState) => {}
// depricated componentWillUpdate = (nextProps, nextState) => {}
render = () => {}
componentDidMount = () => {}
componentDidUpdate = (prevProps, prevState) => {}
componentWillUnmount = () => {}
componentDidCatch = (error, info) => {}
}
- Wrapping components should not use shouldComponentUpdate
- Most of the time, you can use
React.PureComponent
instead of writing your own shouldComponentUpdate - Avoid getDerivedStateFromProps in almost all cases (reference)
shouldComponentUpdate(nextProps, nextState) {
if (this.props.color !== nextProps.color) {
return true;
}
if (this.state.count !== nextState.count) {
return true;
}
return false
}
This pattern is common enough that React provides a helper to use this logic - just inherit from React.PureComponent
See - https://twitter.com/dan_abramov/status/719971882280361985?lang=en
const makeMapStateToProps = (initialState, initialProps) => (state) => ({});
connect(makeMapStateToProps)(Component)
const memo = (fn, areEqual) => class extends React.Component {
shouldComponentUpdate = (nextProps) => {
if (areEqual) {
return !areEqual(this.props, nextProps);
}
return true;
}
render = () => fn(this.props);
};
Usage:
memo(ComponentWithoutProps, () => true)