How to use shouldComponentUpdate with React Hooks?

38,382

Solution 1

Here is the documentation for React.memo

You can pass a function to control the comparison :

const Modal = React.memo(
  props => {...},
  (prevProps, nextProps) => prevProps.show === nextProps.show
);

when the function returns true, the component will not be re-rendered

Solution 2

Also you can use in export statement like:

export default memo(Modal, (prevProps, nextProps) => prevProps.show === nextProps.show) ;
Share:
38,382

Related videos on Youtube

Matin Sasan
Author by

Matin Sasan

“Hardships often prepare ordinary people for an extraordinary destiny.” ~C.S. Lewis. I'm passionate about both formal (programming; JS, Python) and natural languages (I'm a polyglot; English/Persian/German/Turkish/Russian/French/Polish). Just browsing through people's questions is enough to make me humble how much I still don't know and have to learn.

Updated on July 09, 2022

Comments

  • Matin Sasan
    Matin Sasan almost 2 years

    I've been reading these links:
    https://reactjs.org/docs/hooks-faq.html#how-do-i-implement-shouldcomponentupdate
    https://reactjs.org/blog/2018/10/23/react-v-16-6.html

    In the first link it says (https://reactjs.org/docs/hooks-faq.html#from-classes-to-hooks):

    shouldComponentUpdate: See React.memo

    The second link also states that:

    Class components can bail out from rendering when their input props are the same using PureComponent or shouldComponentUpdate. Now you can do the same with function components by wrapping them in React.memo.


    What is desired:

    I want Modal to render only when the Modal is visible (managed by this.props.show)

    For class component:

    shouldComponentUpdate(nextProps, nextState) {
        return nextProps.show !== this.props.show;
    }
    

    How can I use memo instead in a functional component - here, in Modal.jsx?


    The related code:

    Functional component Modal.jsx (I don't know how to check for props.show)

    
    
    import React, { useEffect } from 'react';
    import styles from './Modal.module.css';
    import BackDrop from '../BackDrop/BackDrop';
    
    const Modal = React.memo(props => {
      useEffect(() => console.log('it did update'));
    
      return (
        <React.Fragment>
          <BackDrop show={props.show} clicked={props.modalClosed} />
          <div
            className={styles.Modal}
            style={{
              transform: props.show ? 'translateY(0)' : 'translateY(-100vh)',
              opacity: props.show ? '1' : '0'
            }}>
            {props.children}
          </div>
        </React.Fragment>
      );
    });
    
    export default Modal;
    
    

    The part of class component PizzaMaker jsx that renders Modal:

    
    
     return (
          <React.Fragment>
            <Modal show={this.state.purchasing} modalClosed={this.purchaseCancel}>
              <OrderSummary
                ingredients={this.state.ingredients}
                purchaseCancelled={this.purchaseCancel}
                purchaseContinued={this.purchaseContinue}
                price={this.state.totalPrice}
              />
            </Modal>
            ...
          </React.Fragment>
        );
    
    
    • Olivier Boissé
      Olivier Boissé almost 5 years
      with React.memo, the component will only rerenders if props change, so this is basically what you want
    • Matin Sasan
      Matin Sasan almost 5 years
      I only want it to rerender when props.show is true, not props itself. Because as long as it's invisible, to increase its performance. It gets visible by clicking 'order now' button which triggers props.show to be true and bring up the order summary, that resides within Modal, to be visible.
  • Matin Sasan
    Matin Sasan almost 5 years
    Worked like a charm. Thanks for the KISS approach. And it's exactly what I wanted to know about memo.
  • Muhammad Rafeh Atique
    Muhammad Rafeh Atique almost 3 years
    it's not prevState and nextState, It's a prop (prevProps, nextProps).
  • aznelite89
    aznelite89 over 2 years
    what is different between react.memo and useMemo() in react hooks ?
  • Olivier Boissé
    Olivier Boissé over 2 years
    React.memo is used to prevent rendering of a functional component, useMemo is a hook to prevent recomputing a value inside a functional component
  • JBaczuk
    JBaczuk over 2 years
    Is this the right answer? Because apparently React.memo cannot be counted on like shouldComponentUpdate. From the docs: "This method only exists as a performance optimization. Do not rely on it to “prevent” a render, as this can lead to bugs."
  • Olivier Boissé
    Olivier Boissé over 2 years
    @JBaczuk as you said it seems to be used for performance boost only, so the component might be re-rendered even if the function returns true, strange behavior :(
  • JBaczuk
    JBaczuk over 2 years
    @OlivierBoissé I guess that same warning is given in the docs for shouldComponentUpdate so the answer is correct. ¯\_(ツ)_/¯
  • krupesh Anadkat
    krupesh Anadkat about 2 years
    Elegant, exactly wanted this!