Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent React from re-rendering the whole component

I have a prop called isMobile that displays an external iframe. When I tilt the screen on an iPad, this will change the prop to change values and re-render the iframe (losing all progress inside the iframe).

What is a good way of preventing that re-render? The docs say that I shouldn't use shouldComponentUpdate, since that only is a performance optimization.

like image 729
davorb Avatar asked Oct 18 '18 12:10

davorb


1 Answers

As some answers said, you can use a React.PureComponent that it avoid to re-render with any reason to do it, so you can fix it, separating your Iframe into a single component with the React.PureComponent so it would be like this:

class MyPureIframe extends React.PureComponent {
  render() {
    const {src, width, height} = this.props;
    return (
      <iframe src={src} width={width} height={height} {...whateverProps} />
    );
  }
}

class MyNormalView extends React.Component {
  render() {
    return (
      <div>
       <!--SOME MARKUP HERE-->
       <MyPureIframe src={'https://your-url-to-iframe'} width={100} height={100} />
       <!--SOME MARKUP HERE-->
      </div>
    );
  }
}

So the MyPureIframe only will change (re-render) when some of its props change (src, width, height, or other that you passed down).

In that way no matters in the MyNormalView re-render the deep component MyPureIframe won't re-render until any of its props changed.

I hope it can help you.

Updated May 2020

Because the answer above is related for class based component, if you use a functional component, it mean a function that render some html markup, you can still use this approach as follow.

import React, {memo} from 'react';

const MyPureIframe = memo(({src, width, height}) => (
  <iframe src={src} width={width} height={height} {...whateverProps}/>
));

class MyNormalView extends React.Component {
  render() {
    return (
      <div>
       <!--SOME MARKUP HERE-->
       <MyPureIframe src={'https://your-url-to-iframe'} width={100} height={100} />
       <!--SOME MARKUP HERE-->
      </div>
    );
  }
}

Doing like so, you will get the same result, but using a functional component instead.

Hope it helps you.

like image 137
Juorder Gonzalez Avatar answered Nov 06 '22 10:11

Juorder Gonzalez