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

Redux Saga请求完成后使用返回数据渲染visx词云出现"read-only"报错

问题根因

  1. @visx/wordcloud 底层依赖 d3-cloud 布局库,该库的布局计算逻辑会直接修改传入的words数组内的每一个对象,写入 x、y、size、rotate 等布局属性。
  2. 你从Redux中获取的 aggregation.data 内的对象是被冻结的只读对象:Redux 开发环境默认会冻结所有状态对象防止直接修改,如果你使用了Immer等不可变工具也会产生冻结对象。d3 尝试向只读对象写入属性时,就会抛出对应报错。
  3. 静态数据是普通可写对象,因此运行正常。你之前做的克隆操作仅处理了数组外层,没有克隆数组内部的每个词对象,原对象还是只读状态,因此报错没有解决。

解决方法

在将数据传给词云组件前,对数组内的每个词对象做一次浅克隆,生成全新的可写对象供d3修改即可,有两种实现位置可选:

方案1:调用词云组件时处理

在 AggregationShowComponent 中传入参数时做克隆:

<WordCloud
  // 对每个词对象做浅拷贝,生成全新可写对象
  words={aggregation.data.map(item => ({ ...item }))}
  width={1024}
  height={600}
  spiral="archimedean"
  rotate="0"
/>

方案2:词云组件内部统一处理

在 WordCloud 组件内部对传入的参数做克隆,一劳永逸避免后续调用出问题:

export default function WordCloud({ words, width, height, rotate = 0, spiral = 'archimedean' }: WordCloudProps) {
  // 先克隆所有词对象,避免修改原只读数据
  const clonedWords = words.map(item => ({ ...item }))

  const fontScale = scaleLog({
    domain: [Math.min(...clonedWords.map((w) => w.value)), Math.max(...clonedWords.map((w) => w.value))],
    range: [10, 100],
  });
  const fontSizeSetter = (datum: WordData) => fontScale(datum.value);

  return (
    <>
      <Wordcloud
        words={clonedWords}
        width={width}
        height={height}
        fontSize={fontSizeSetter}
        font={'Impact'}
        padding={2}
        spiral={spiral}
        rotate={rotate}
        random={fixedValueGenerator}
      >
        {(cloudWords) =>
          cloudWords.map((w, i) => (
            <Text
              key={w.text}
              fill={colors[i % colors.length]}
              textAnchor={'middle'}
              transform={`translate(${w.x}, ${w.y}) rotate(${w.rotate})`}
              fontSize={w.size}
              fontFamily={w.font}
            >
              {w.text}
            </Text>
          ))
        }
      </Wordcloud>
    </>
  );
}

如果你的词对象还有嵌套属性,把上述的浅克隆替换为深克隆即可,比如使用浏览器原生的 structuredClone() 方法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 05:45:02