首页 > 解决方案 > 修改状态变量的属性

问题描述

我在我的 React 应用程序中使用heatmap.js 。我需要对浏览器调整大小和重新计算数据做出反应。为了检测浏览器调整大小,我使用react-use-measure包。

工作代码:

import useMeasure from 'react-use-measure';
import HeatMapJs from 'heatmap-ts';

export const Heatmap: FC<HeatmapProps> = ({
  backgroundImageUrl,
  data,
  opacity = 0.5,
  radius = 20,
}: HeatmapProps) => {
  const [ref, bounds] = useMeasure({ polyfill: ResizeObserver });
  const [hm, setHm] = useState<HeatMapJs>();

  useEffect(() => {
    setHm(
      new HeatMapJs({
        container: document.getElementById('hm') || undefined,
        opacity,
        radius,
      })
    );
  }, []);

  useEffect(() => {
    if (data.length && bounds.width) {
      const ratioX = bounds.width / 1280; // hardcoded width of full image
      const ratioY = bounds.height / 720;
      let min: number = data[0].value;
      let max: number = data[0].value;
      const len = data.length;
      const dataWithRatio: HeatmapPoint[] = [];
      for (let i = 0; i < len; i++) {
        const item = data[i];
        const v = item.value;
        min = min < v ? min : v;
        max = max > v ? max : v;
        dataWithRatio.push({
          x: Math.round(item.x * ratioX),
          y: Math.round(item.y * ratioY),
          value: item.value,
        } as HeatmapPoint);
      }
      if (min === max) {
        min = 0;
      }
      hm?.setData({
        min: min,
        max: max,
        data: dataWithRatio,
      });
    }
  }, [bounds]);

  return (
    <div>
      <div id="hm" ref={ref}>
        <img src={backgroundImageUrl} />
      </div>
    </div>
  );
};

我使用状态变量hm- 它必须创建一次,因为每次创建时都会将画布添加到div#hm. 然后,当bounds更改生效时,我计算新数据添加替换现有的hm.

这可行,但看起来不遵循 React 状态的不变性规则,因为我更改了hm.

我尝试将常规变量用于hm:声明 const 而不是 state,在第一个效果中实例化它并在第二个效果中使用,但如果发生的话undefined

这应该如何以最正确的方式完成?我正在考虑手动删除旧画布,但它看起来像相当复杂的冗余。

标签: reactjstypescriptheatmap

解决方案


推荐阅读