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
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
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
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'));