简体   繁体   English

在 React 中重新排序元素而不导致它们重新渲染

[英]Reordering elements in React without causing them to rerender

I'm animating SVG with React, and I have have a few SVG elements that get rotated and reordered in JSX to change their stacking order.我正在使用 React 为 SVG 制作动画,并且我有一些 SVG 元素在 JSX 中进行旋转和重新排序以更改其堆叠顺序。 (SVG doesn't have a z-index property, so the elements need to be reordered manually.) My JSX looks like: (SVG 没有z-index属性,因此需要手动重新排序元素。)我的 JSX 看起来像:

<svg>
  <g>
    <Rect key={'rect0'} />
    <Rect key={'rect1'} />
    <Rect key={'rect2'} />
    <Rect key={'rect3'} />
  </g>
</svg>

The SVG result looks like: SVG 结果如下所示:

<svg>
  <g>
    <rect>
    <rect>
    <rect>
    <rect>
  </g>
</svg>

My problem is that when I change the order of these components, the rotated elements' rotation transition gets interrupted because the rotated elements are being re-rendered when their order gets changed.我的问题是,当我更改这些组件的顺序时,旋转元素的旋转过渡会中断,因为当它们的顺序改变时,旋转的元素会被重新渲染。 I need the rotation transition to be smooth.我需要平滑的旋转过渡。 In some cases it may be possible to rotate a parent of the component instead, but in this case that feels like a hacky workaround.在某些情况下,可能可以改为旋转组件的父级,但在这种情况下,这感觉就像一个 hacky 解决方法。 It would be preferable to have the component containing the rects have their rotation as part of their state.最好让包含矩形的组件将其旋转作为其 state 的一部分。

I tried using shouldComponentUpdate , but rotation is in the state.我尝试使用shouldComponentUpdate ,但旋转在 state 中。 If I compare state in shouldComponentUpdate to determine if the element should rotate, it re-renders, and if I always return false, the element doesn't rotate.如果我在 shouldComponentUpdate 中比较 state 以确定元素是否应该旋转,它会重新渲染,如果我总是返回 false,则元素不会旋转。 I'll update my question with this.我会用这个更新我的问题。 So I tried this:所以我尝试了这个:

shouldComponentUpdate(nextProps, nextState) {
    return (nextState.rotation !== this.state.rotation);
}

Can this be done?这可以做到吗? Is there a straightforward solution?有直接的解决方案吗?

I'll create a working example when I have spare time.当我有空闲时间时,我将创建一个工作示例。

You can use shouldComponentUpdate to decide if it should re-render.您可以使用 shouldComponentUpdate 来决定它是否应该重新渲染。

class Elements extends Component {
  shouldComponentUpdate(nextProps, nextState) {
    // This is just an example, but you can track the number of elements 
    // for instance and decide not to re-render if they're the same
    if (this.state.number === nextState.number) {
      return false;
    } else {
      return true;
    }
  }

  render() {
    return <svg>
      <g>
        <Rect key={'rect0'} />
        <Rect key={'rect1'} />
        <Rect key={'rect2'} />
        <Rect key={'rect3'} />
     </g>
    </svg>
  }
}

In addition you could also consider deriving from PureComponent as it does a shallow check on props and state.此外,您还可以考虑从 PureComponent 派生,因为它对 props 和 state 进行了浅层检查。

class Elements extends PureComponent {
  render() {
    return <svg>
      <g>
        <Rect key={'rect0'} />
        <Rect key={'rect1'} />
        <Rect key={'rect2'} />
        <Rect key={'rect3'} />
     </g>
    </svg>
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM