如何防止我的功能组件使用 React 备忘录或 React 钩子重新渲染?

Posted

技术标签:

【中文标题】如何防止我的功能组件使用 React 备忘录或 React 钩子重新渲染?【英文标题】:How can I prevent my functional component from re-rendering with React memo or React hooks? 【发布时间】:2019-07-23 14:56:06 【问题描述】:

hiddenLogo 改变值时,组件被重新渲染。我希望这个组件从不重新渲染,即使它的道具发生变化。使用类组件,我可以通过像这样实现 sCU 来做到这一点:

shouldComponentUpdate() 
  return false;

但是有没有办法使用 React 钩子/React 备忘录?

这是我的组件的样子:

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;

【问题讨论】:

【参考方案1】:

React.memo 与React.PureComponent 相同

当您不想更新您认为是静态的组件时,可以使用它,与PureCompoment 相同。

对于类组件:

class MyComponents extends React.PureCompoment 

对于函数组件:

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

所以它只是用React.memo 创建一个组件

要验证您的组件没有渲染,您可以 在反应extension 中激活HightlightUpdates 并检查您的components reaction rendering

【讨论】:

React.memo 将在其 props 更改时重新渲染组件。我的问题是如何让我的组件从不重新渲染,即使道具发生变化,并且不使用类。 将memo的第二个参数改写为() => true;【参考方案2】:

正如 G.aziz 所说,React.memo 的功能类似于纯组件。但是,您也可以通过向它传递一个定义什么是相等的函数来调整它的行为。基本上,这个函数就是 shouldComponentUpdate,除非你希望它渲染时返回 true。

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

const MyComponent = React.memo(props => 
  return /*whatever jsx you like */
, areEqual);

【讨论】:

太棒了!谢谢! 如何对 props 进行深度比较? React.memo 只比较 newProps 和 oldProps,我们如何比较 newState 和 oldState 来决定何时重新渲染? @QuocVanTang useState 钩子会自行检查以确保值已更改,如果未更改则跳过渲染。除此之外,在功能组件中设置状态时,您无法阻止重新渲染。根据您的组件的功能,您可以使用 useMemo 或 useCallback 跳过渲染中的一些计算。 关于React.memo,文档说,“此方法仅作为性能优化存在。不要依赖它来“阻止”渲染,因为这可能会导致错误。” (reactjs.org/docs/react-api.html#reactmemo)。有谁知道更多关于可能发生的错误?【参考方案3】:

我们可以使用memo 来阻止函数组件中的渲染,仅用于优化目标。根据 React 文档:

此方法仅作为性能优化存在。不要依赖它来“阻止”渲染,因为这可能会导致错误。

【讨论】:

【参考方案4】:

根据反应文档:- [https://reactjs.org/docs/react-api.html][1]

反应。备忘录是一个高阶组件。如果您的组件呈现 给定相同的道具,结果相同,您可以将其包装在对 React 的调用中。 在某些情况下通过记忆结果来提高性能的备忘录。 这意味着 React 将跳过渲染组件,并重用 最后渲染的结果。

为了实际理解,我看到这两个视频非常好,如果您也想清楚概念,最好观看,这样可以节省您的时间。

免责声明:-这不是我的 YouTube 频道。

https://youtu.be/qySZIzZvZOY [使用备忘录挂钩] https://youtu.be/7TaBhrnPH78 [基于类的组件]

【讨论】:

以上是关于如何防止我的功能组件使用 React 备忘录或 React 钩子重新渲染?的主要内容,如果未能解决你的问题,请参考以下文章

React Hook 功能组件防止重新渲染

React备忘录

使用 setInterval 时如何防止 React 重新渲染整个组件

每次使用相同的给定道具 React Memo 渲染

React-native 组件缓存(或防止卸载)(react-navigation)

在 React 中,如何防止组件的 CSS 导入应用到整个应用程序?