5
votes

I tried to use React.memo in my functional component . It takes props from parent components. But i pass the same props to my 'memo' component.It renders every time.Same thing happened when i use React.Purecomponent.But When I use shouldcomponentupdate rerender did not happens: Why?

I have a toggle variable in my initial State .

enter image description here when i resized window handleResize called and my header reseted.This mean my toggle false is now ]

enter image description here .I passed toggle variable to my child component .

enter image description here And then i take it from props.

enter image description here .. Sorry i have some typing mistakes in this question

2
example please; remember that memo/PureComponent does a shallow comparison - r g
You might want to add some code, so that the readers can understand it better. - Eliâ Melfior
Please share the code snippets instead of images - Shubham Khatri

2 Answers

12
votes

You are passing a new toggleHamburger prop every time.

In fact this is the most common performance killer in React apps I have seen. Passing a new closure as an event handler / callback each time.

To solve this issue, I would recommend the useCallback() hook, or, in your case a method, as the outer component is a class:

class ... {
  toggleHamburger = () => this.setState(({toggle}) => ({toggle: !toggle}));
  ...
    <HamburgerButton toggleHamburger={this.toggleHamburger} />
}

A component wrapped with React.memo() will only render once if called with the same props:

const Comp = React.memo(props => {
  console.log('Rendering...');
  return props.a;
});

const props = {a: 1};
const at = document.getElementById('app');
render();
render();
render();

function render() {
  console.log('Called render()'); 
  ReactDOM.render(<Comp {...props} />, at);
}
<div id="app"></div>
<script src="//unpkg.com/react/umd/react.production.min.js"></script>
<script src="//unpkg.com/react-dom/umd/react-dom.production.min.js"></script>
-1
votes
    export default class extends Component {
  shouldComponentUpdate(nextProps) {
    const { toggle } = this.props;
    return nextProps.toggle !== toggle;
  }

  render() {
    console.log('Rendering ...');
    const { toggleHamburger, toggle } = this.props;
    return (
      <svg viewBox="0 0 96 96" height="1em" onClick={toggleHamburger} {...{ style }}>
        <Motion
          style={{
            x: spring(toggle ? 1 : 0, presets.wobbly),
            y: spring(toggle ? 0 : 1, presets.wobbly)
          }}
        >
          {({ x, y }) => (
            <g
              id="navicon"
              fill="none"
              stroke="currentColor"
              strokeWidth="14"
              strokeLinecap="round"
              strokeLinejoin="round"
            >
              <line
                transform={`translate(${x * 12}, ${x * -7}) rotate(${x * 45}, 7, 26)`}
                x1="7"
                y1="26"
                x2="89"
                y2="26"
              />
              <line
                transform={`translate(${x * 12}, ${x * 7}) rotate(${x * -45}, 7, 70)`}
                x1="7"
                y1="70"
                x2="89"
                y2="70"
              />
              <line
                transform={`translate(${x * -96})`}
                opacity={y}
                x1="7"
                y1="48"
                x2="89"
                y2="48"
              />
            </g>
          )}
        </Motion>
      </svg>
    );
  }
}