You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

key相同场景下React是否会忽略ArrayBuffer类型props的重渲染触发?

React组件复用与重渲染逻辑

首先明确React的两个核心规则:

  • 列表渲染时,React通过key属性匹配前后两次渲染的元素,只要key相同、组件类型相同,就会复用已有的组件实例,不会销毁旧实例再创建新实例。
  • 空依赖数组的useEffect只会在组件第一次挂载完成后执行一次,后续不管prop如何更新,都不会重新触发,只有组件被销毁后再次挂载才会重新执行。

问题根因

  1. 你怀疑array buffer导致React忽略prop更新是不成立的:React对所有类型的prop都做浅比较(引用比对),只要你传入的thumbnail是新的array buffer引用,React会正常触发Asset组件的重渲染,你能看到AssetView的渲染日志也验证了这一点,effect没触发和prop类型无关。
  2. 核心问题就是不同标签页的Asset用了重复的document_id作为key:
    切换标签时,React发现新的Asset列表里有和之前key相同的组件,就直接复用了旧的组件实例,不会触发重新挂载,所以你写的空依赖effect自然不会重新执行,实例里的thumbnailUrl状态还停留在上一次生成的结果,就出现了切回标签A显示的还是标签B的Blob-2的问题。
  3. 至于为什么会生成Blob-2:当你第一次切换到标签B时,如果此时旧的Asset实例已经被销毁(比如之前标签A的内容被完全卸载),React会为标签B的同keyAsset创建新实例,触发effect生成Blob-2,之后再切回标签A,又会复用这个带Blob-2的实例,就出现了错乱。

解决方案

你预期不同标签页的同document_id资产各自独立保留自己的blob地址,最优解就是修改key的生成规则,保证全局唯一:

<AssetContainer>
{assets.map((asset) => (
      <Asset
        key={`${当前标签ID}-${asset.document_id}`}
        thumbnail={asset.thumbnail!.image!}
        thumbnailFormat={asset.thumbnail!.format!}
        hasClaim={!!asset.provenance}
        errors={asset.errors}
        size="80px"
      />
    )
)}
</AssetContainer>

这样不同标签的资产key不同,React会为每个标签的资产创建独立的组件实例,每个实例的effect只会在挂载时执行一次,生成各自的blob地址,切换标签时实例独立存储状态,不会出现错乱。

如果你不想修改每个Asset的key,也可以给AssetContainer加上标签ID作为key:

<AssetContainer key={当前标签ID}>
  {/* 原有内容 */}
</AssetContainer>

这样切换标签时整个AssetContainer会销毁重建,内部所有资产组件也会重新挂载生成对应blob,不过如果资产列表很长的话,性能会比单独修改Asset的key差。


内容的提问来源于stack exchange,提问作者Dave Stein

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 10:36:03