【问题标题】:javascript / react - switching the properties of two objects in an array in react state without triggering a re-renderjavascript / react - 在反应状态下切换数组中两个对象的属性而不触发重新渲染
【发布时间】:2019-07-18 18:45:29
【问题描述】:

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

所以给定:

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

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

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

尽可能少的代码。

理由:

我正在使用一个画布库做出反应,其中有两个可拖动的画布对象 从处于状态的数组需要切换 z 顺序而不触发 React 的重新渲染(否则画布会丢失对象被拖动位置的内存......)。

所以当我试图简单地做:

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];

那些canvasImages失去任何拖动位置:

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}`}
  />
)

【问题讨论】:

  • 在 React 组件中包装第三方库时,通常需要使用 shouldComponentUpdate 阻止更新,并让第三方代码自行更新。
  • 嗯 - 它确实需要更新,像“isInteractable prop”这样的东西是从父级驱动的。但我也说整个组件重新安装,因为呈现每个项目的数组发生了变化。我认为这就是重新设置位置的原因。
  • shouldComponentUpdate 让您过滤哪些内容应该更新或不更新。此外,当第三方有一个根本不应该重新初始化的实例时,您应该手动处理更新,通过他们的 API 将新值传递给第三方实例。
  • 我说的是“第三方”,但它可能是您自己的画布、iframe 等。您不需要使用 React 进行更新,保持手动更新只是最佳实践最低限度。
  • 确保您正确使用key 属性。最好使用某种idcanvasImage 设置密钥。在密钥中使用index 是一种不好的方法。这就是它被重新安装的原因。

标签: javascript reactjs lodash konvajs react-konva


【解决方案1】:

如我所见,您正在使用 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}
  />
)

【讨论】:

    猜你喜欢
    • 2018-04-04
    • 2020-08-12
    • 2022-07-12
    • 2020-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-18
    相关资源
    最近更新 更多