javascript / react - 在不触发重新渲染的情况下,在反应状态下切换数组中两个对象的属性

javascript / react - switching the properties of two objects in an array in react state without triggering a re-render

我只需要将一个数组对象的键替换为另一个。我将提供一个理由,说明为什么我认为我之后需要这样做以尝试避免 TLDR,以防有人发现我可能根本不需要这样做的更深层原因。

所以给出:

canvasImages = [
  {
    property1: 1
    property2: 2
  },
  {
    property1: 3,
    property2: 4,
  }
]

我想在数组中指定两个对象并循环遍历它们的属性(因为属性列表可能很长),然后说(伪代码):

canvasImages[1].property1 = canvasImages[2].property1;
canvasImages[2].property2 = canvasImages[2].property2;
etc...

使用尽可能少的代码。

理由:

我正在使用与 canvas 库的反应,其中有两个可拖动的 canvas 对象 来自处于状态的数组需要切换 z 顺序而不触发 react 的重新渲染(否则 canvas 会丢失对象被拖动位置的记忆...)。

所以当我尝试简单地做:

const {canvasImages} = this.state;
const oldIndex = 1; const newIndex = 2;
const reorderedCanvasImages = reorderArray(canvasImages,oldIndex,newIndex) //unshown function, just reorders the array
this.setState({
  canvasImages: reorderedCanvasImages //this triggers a re-mount of the URLImage component
});

或:

const newCanvasImages = _.clonedeep(canvasImages);
const oldIndex = 1; const newIndex = 2;
const reorderedCanvasImages = reorderArray(canvasImages,oldIndex,newIndex) 
this.state.canvasImage[0] = newCanvasImages[0];
this.state.canvasImage[1] = newCanvasImages[1];

那些canvas图像丢失任何拖动位置:

canvasImages.map((canvasImage, index) => {
//remounted after setState on canvasImages or even after changing array positions within this.state.canvasImages
return (
  <URLImage
    src={`${canvasImage.image}`}
    isInteractable={activeCanvasImageIndex === index}
    className={`canvas__interactable`}
    key={`canvas__interactable--${canvasImage.object}_${index}`}
  />
)

正如我所看到的,您正在使用 index 和 key 属性中的一个对象:

key={`canvas__interactable--${canvasImage.object}_${index}`}

当您重新排序对象时,您将拥有与旧密钥不同的全新密钥。在那种情况下,React 认为它是新组件,因此它删除旧组件并创建新组件。为避免它,只需对数组中的每个项目使用 uniq id

const canvasImages = [
  {
    id: 1,
    property1: 1
    property2: 2
  },
  {
    id: 2,
    property1: 3,
    property2: 4,
  }
]

canvasImages.map((canvasImage, index) => {
return (
  <URLImage
    src={`${canvasImage.image}`}
    isInteractable={activeCanvasImageIndex === index}
    className={`canvas__interactable`}
    key={canvasImage.id}
  />
)