如何防止React重新渲染整个组件

9
我有一个名为 isMobile 的属性,用于显示外部iframe。当我在iPad上倾斜屏幕时,该属性将更改值并重新渲染iframe(导致iframe内所有进度丢失)。
有什么好的方法可以防止重新渲染?根据文档,不应使用shouldComponentUpdate,因为那只是性能优化。

React 的性能优化与组件的重新渲染或否有关,因此请使用这个生命周期方法来检查您的属性并决定是否重新渲染。 - philipjc
按照文档所述,如果isMobile从未更改,则只需使用React.PureComponent,那么iframe就不会重新渲染。 - Fabio Antunes
你没有添加redux标签,你是在使用redux还是setState - HMR
@HMR 我正在使用 Redux。 - davorb
在这种情况下,如果您使用connect并且状态没有改变,则不应调用渲染函数。如果您使用类似path=something.concat(another)的方式从父组件设置props,则每次渲染都会更改props。您应该发布将props传递给组件的部分。 - HMR
@HMR 状态确实会发生变化。 - davorb
2个回答

5

正如一些答案所述,你可以使用 React.PureComponent 来避免无谓的重新渲染,这样你就可以解决问题,将你的 Iframe 分离成一个单独的组件并与 React.PureComponent 结合使用,代码如下:

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>
    );
  }
}

因此,只有当MyPureIframe的某些props发生更改(例如src、width、height或您传递的其他props)时,它才会改变(重新渲染)。

因此,在MyNormalView重新呈现深层组件MyPureIframe无论如何都不会重新渲染,直到其任何一个props发生更改。

希望这能对你有所帮助。

更新于2020年5月

因为上面的答案与基于类的组件有关,如果您使用函数式组件,也就是呈现某些HTML标记的函数,则仍然可以按照以下方式使用此方法。

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>
    );
  }
}

这样做,您将获得相同的结果,但是使用函数组件。

希望能对您有所帮助。


对于TypeScript的快乐(尽管这里没有标签,所以我不会添加答案):const MyPureIframe = memo((props: React.DetailedHTMLProps<React.IframeHTMLAttributes<HTMLIFrameElement>, HTMLIFrameElement>) => <iframe src={props.src} />); eslint可能还需要一个displayNameMyPureIframe.displayName = 'MyPureIFrame'; - undefined

0

shouldComponentUpdate并不是更好的方法。文档中说它未来可能会忽略shouldComponentUpdate的变化。 请尝试使用称为memoize的概念,它比PureComponent更好。


3
你能提供一些代码来解释这个概念吗?这对于读者来说将是有用的信息。 - Andy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接