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

Posted

技术标签:

【中文标题】每次使用相同的给定道具 React Memo 渲染【英文标题】:React Memo Renders Every Time with same given props 【发布时间】:2019-07-09 11:56:42 【问题描述】:

我尝试在我的功能组件中使用 React.memo。它从父组件中获取道具。但是我将相同的道具传递给我的“备忘录”组件。它每次都会渲染。当我使用 React.Purecomponent 时发生了同样的事情。但是当我使用 shouldcomponentupdate 时没有发生重新渲染:为什么?

我的初始状态中有一个切换变量。

当我调用了调整大小的窗口 handleResize 并重置了我的标题时。这意味着我的切换错误现在是]

。我将切换变量传递给我的子组件。

然后我从道具中取出。

.. 对不起,我在这个问题中有一些打字错误

【问题讨论】:

请举例;请记住,memo/PureComponent 进行了浅比较 您可能需要添加一些代码,以便读者更好地理解它。 请分享代码sn-ps而不是图片 【参考方案1】:
    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"  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>
    );
  

【讨论】:

【参考方案2】:

你每次都在传递一个新的 toggleHamburger 道具。

事实上,这是我见过的 React 应用程序中最常见的性能杀手。每次都将新的闭包作为事件处理程序/回调传递。

要解决这个问题,我会推荐 useCallback() 钩子,或者在你的情况下是一个方法,因为外部组件是一个类:

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


使用React.memo() 包裹的组件在使用 same 属性调用时只会呈现一次:

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>

【讨论】:

我不明白你这是什么意思。 每次都将新的闭包作为事件处理程序/回调传递 @KhorenGrigoryan () =&gt; this.setState( toggle: !toggle ) 这会创建一个新的闭包(函数),因此每次都会使用不同的道具。 您认为哪种方式最好? @KhorenGrigoryan 用建议更新了答案 谢谢伙计 .. 它有效 ))) .. 最后一个问题。为什么如果我每次 shouldComponentUpdate 都可以创建新道具,但 memopureComponent 却不行。

以上是关于每次使用相同的给定道具 React Memo 渲染的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的标题每次渲染都已经使用 React.memo?

React-router-dom 渲染道具没有返回任何组件

使用 React.memo、useCallback、useMemo 防止对象重新渲染

React.memo()、useCallback()、useMemo() 区别及基本使用

React.memo 不适用于功能组件和谷歌地图

为啥在 React 中,当父组件重新渲染时子组件不会重新渲染(子组件没有被 React.memo 包裹)?