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

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

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

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

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

然后我从道具中取出。

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

【问题讨论】:

  • 请举例;请记住,memo/PureComponent 进行了浅比较
  • 您可能需要添加一些代码,以便读者更好地理解它。
  • 请分享代码sn-ps而不是图片

标签: reactjs


【解决方案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" height="1em" 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 却不行。
    猜你喜欢
    • 1970-01-01
    • 2023-02-26
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    • 2017-12-05
    • 2020-03-26
    • 2020-09-05
    • 2017-06-02
    相关资源
    最近更新 更多