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.
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.
- Performance optimisation for React is about re-rendering the ponents or not, so yes use this life cycle method to check your props and re-render or not. – philipjc Commented Oct 18, 2018 at 12:47
-
As the docs say just use the React.PureComponent if
isMobile
never changes then the iframe is never rerendered – Fabio Antunes Commented Oct 18, 2018 at 12:49 -
You did not add redux tag, Are you using redux or
setState
? – HMR Commented Oct 18, 2018 at 12:55 - @HMR I'm using Redux – davorb Commented Oct 18, 2018 at 13:27
-
In that case the render function should not be called if you use connect and state didn't change. If you set props from parent with something like
path=something.concat(another)
then props will change every render. You should post the part where you pass the props to the ponent. – HMR Commented Oct 18, 2018 at 13:30
2 Answers
Reset to default 5As 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 ponent 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 ponent 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 ponent, if you use a functional ponent, 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 ponent instead.
Hope it helps you.
shouldComponentUpdate is not a better approach. The document says it can ignore the changes to shouldComponentUpdate in future.
Please try using the concept called memoize
which is better than PureComponent