MENU
React.memo
If you wish to have the functionality of shouldComponentUpadate() for a performance boost but do not want to use a class component, you can wrap your function component in a higher-order function with React.memo (differentiate this from the React.useMemo hook!).
Since the props has not changed, Demo is not repeatedly rendered and the last result is used.
RESETRUNFULL
RESETRUNFULL
const Demo = React.memo((props)=>{
console.log('rendering Demo');
return <h2>Testing</h2>;});class Example extends React.Component{
constructor(props){
super(props);
this.state={a:0};
}
componentDidMount(){
setInterval(()=>{
this.setState((state,props)=>({a:state.a+1}));
},1000);
}
render(){
console.log('rendering Example'); //return (<Demo y={this.state.a}/>); // re-renders Demo repeatedly
return (<Demo y={1}/>);
}}ReactDOM.render(
<Example />,
document.querySelector('div'));
React.memo only checks for prop changes. If your function component wrapped in React.memo has a useState, useReducer or useContext Hook in its implementation, it will still rerender when state or context change.
More about hooks will be explained in Chapters 12-24. Specifically, to simulate the shouldComponentUpdate() optimization in function components, we can resort to the useCallback, useMemo, and useReducer hooks.
By default React.memo will only shallowly compare the props object.
RESETRUNFULL
RESETRUNFULL
const Demo = React.memo(props=>{
console.log('rendering Demo');
return <h2>{props.y.a.b}</h2>;});class Example extends React.Component{
constructor(props){
super(props);
this.state={a:{b:0}};
}
componentDidMount(){
setInterval(()=>{
this.setState((state,props)=>({a:{b:0}})); // different object assumed
},1000);
}
render(){
console.log('rendering Example');
return (<Demo y={this.state}/>);
}}ReactDOM.render(<Example />,
document.querySelector('div'));
If you want control over the comparison, you can also provide a custom comparison function as the second argument.
RESETRUNFULL
RESETRUNFULL
function areEqual(prevProps, nextProps) {
return (prevProps.y.a.b===nextProps.y.a.b);}const Demo = React.memo(props=>{
console.log('rendering Demo');
return <h2>{props.y.a.b}</h2>;},areEqual);class Example extends React.Component{
constructor(props){
super(props);
this.state={a:{b:0}};
}
componentDidMount(){
setInterval(()=>{
this.setState((state,props)=>({a:{b:0}}));
},1000);
}
render(){
console.log('rendering Example');
return (<Demo y={this.state}/>);
}}ReactDOM.render(<Example />,
document.querySelector('div'));