53

When hiddenLogo changes value, the component is re-rendered. I want this component to never re-render, even if its props change. With a class component I could do this by implementing sCU like so:

shouldComponentUpdate() {
  return false;
}

But is there a way to do with with React hooks/React memo?

Here's what my component looks like:

import React, { useEffect } from 'react';
import PropTypes from 'prop-types';

import ConnectedSpringLogo from '../../containers/ConnectedSpringLogo';

import { Wrapper, InnerWrapper } from './styles';
import TitleBar from '../../components/TitleBar';

const propTypes = {
  showLogo: PropTypes.func.isRequired,
  hideLogo: PropTypes.func.isRequired,
  hiddenLogo: PropTypes.bool.isRequired
};

const Splash = ({ showLogo, hideLogo, hiddenLogo }) => {
  useEffect(() => {
    if (hiddenLogo) {
      console.log('Logo has been hidden');
    }
    else {
      showLogo();

      setTimeout(() => {
        hideLogo();
      }, 5000);
    }
  }, [hiddenLogo]);

  return (
    <Wrapper>
      <TitleBar />
      <InnerWrapper>
        <ConnectedSpringLogo size="100" />
      </InnerWrapper>
    </Wrapper>
  );
};

Splash.propTypes = propTypes;

export default Splash;
j.doe
  • 1,214
  • 2
  • 12
  • 28

4 Answers4

79

As G.aziz said, React.memo functions similarly to pure component. However, you can also adjust its behavior by passing it a function which defines what counts as equal. Basically, this function is shouldComponentUpdate, except you return true if you want it to not render.

const areEqual = (prevProps, nextProps) => true;

const MyComponent = React.memo(props => {
  return /*whatever jsx you like */
}, areEqual);
Nicholas Tower
  • 72,740
  • 7
  • 86
  • 98
  • Awesome! Thank you! – j.doe Mar 01 '19 at 15:39
  • 1
    How can we perform a deep comparison of props? – HalfWebDev Aug 09 '19 at 12:45
  • 1
    React.memo only compare newProps and oldProps, how can we compare newState and oldState to decide when to re-render? – Quoc Van Tang Sep 26 '19 at 00:17
  • 1
    @QuocVanTang the useState hook will do its own check to make sure the value changed, and skip the render if it did not. Other than that, you can't prevent a rerender when setting state in a functional component. Depending on what your component does, you can use useMemo or useCallback to skip some calculations in the render. – Nicholas Tower Sep 26 '19 at 01:26
  • Thanks for reply, I suppose if we have the oldState is { xyz: 1 }, then we set the newState to it as the equal value { xyz: 1} (new reference object but equal as deep compare). For now, it still re-render because react hooks do shallow compare so I want to skip the re-render for this case – Quoc Van Tang Sep 26 '19 at 02:01
  • 18
    Regarding `React.memo`, the docs say, "This method only exists as a performance optimization. Do not rely on it to “prevent” a render, as this can lead to bugs." (https://reactjs.org/docs/react-api.html#reactmemo). Does anyone know more about what bugs can occur? – AlexJ Dec 19 '19 at 19:15
  • I think this (https://stackoverflow.com/a/61547432/839847) is a pretty good discussion of the potential costs of using `React.memo` - although the discussion is around performance costs, not potential bugs. – bergie3000 Jan 16 '21 at 08:18
  • I have a similar problem, can I get a solution? https://stackoverflow.com/questions/72176305/changing-props-state-using-api-causes-infinite-loop/72186468#72186468 – Shubham Singhvi May 10 '22 at 15:19
18

React.memo is same thing as React.PureComponent

You can use it when you don't want to update a component that you think is static so, Same thing as PureCompoment.

For class Components:

class MyComponents extends React.PureCompoment {}

For function Components:

const Mycomponents = React.memo(props => {
  return <div> No updates on this component when rendering </div>;
});

So it's just creating a component with React.memo

To verify that your component doesn't render you can just activate HightlightUpdates in react extension and check your components reaction on rendering

Aziz.G
  • 3,599
  • 2
  • 17
  • 35
  • 3
    React.memo will re-render the component when its props change. My question is how can I make my component *never* re-render even if props change, and **without** using a class. – j.doe Mar 01 '19 at 15:32
  • 4
    Rewrite the second parameter of memo to () => true; – DanteTheSmith May 09 '19 at 12:22
11

We can use memo for prevent render in function components for optimization goal only. According React document:

This method only exists as a performance optimization. Do not rely on it to “prevent” a render, as this can lead to bugs.

Masih Jahangiri
  • 9,489
  • 3
  • 45
  • 51
0

According to react documentation:- [https://reactjs.org/docs/react-api.html][1]

React. memo is a higher order component. If your component renders the same result given the same props, you can wrap it in a call to React. memo for a performance boost in some cases by memoizing the result. This means that React will skip rendering the component, and reuse the last rendered result.

For practical understanding I came across these two videos they are very good if you wanna clear concepts also, better to watch so it'll save your time.

Disclaimer:- This is not my YouTube channel.

AKASH GUDADHE
  • 317
  • 1
  • 6
  • 15