ChartJS zoom/pan onPan 事件未在 React useEffect 挂钩中触发

ChartJS zoom/pan onPan event not firing in React useEffect hook

我 运行 发现 ChartJS 的 Pan/Zoom 插件事件 onPan 在从 useEffect 挂钩内部分配图表配置时未触发的问题。我正在监听平移和缩放事件并相应地触发事件总线以同步多个图表的 zoom/pan 边界。只有 onPan 才会出现问题,因为 onZoom 工作得很好。

这是一般的重要代码(这都在功能组件中):

useEffect(() => {
    if(applicableEffectCondition.isMet) {
      return; // to prevent infinite loop
    }

    // do code magic ...

    function dispatchInteractEvent(reference: MutableRefObject < any | undefined > ) {
        dispatch({
            type: "@@charts/INTERACT",
            payload: {
                sender: reference.current.id,
                x: {
                    min: reference.current.scales.x.min,
                    max: reference.current.scales.x.max,
                },
            }
        });
    }

    const options: ChartOptions = {
        // ...

        plugins: {

            zoom: {
                limits: {
                    // minimum X value & maximum X value
                    x: {
                        min: Math.min(...labelsNumber),
                        max: Math.max(...labelsNumber)
                    },
                },
                zoom: {
                    wheel: {
                        enabled: true,
                        speed: 0.1,
                    },
                    pinch: {
                        enabled: true
                    },
                    mode: 'x',
                    onZoom: () => {
                        alert("I am zooming!");
                        dispatchInteractEvent(chartRef);
                    }
                },
                pan: {
                    enabled: true,
                    mode: 'x',

                    rangeMin: {
                        y: allDataMin
                    },
                    rangeMax: {
                        y: allDataMax
                    },

                    onPan: () => {
                        alert("I am panning!");
                        dispatchInteractEvent(chartRef);
                    }
                }
                as any
            }
        },
    };

    setChartOptions(options); // use state

    const data: ChartData = {
        labels: labelsString,
        datasets: datasetState.getDatasets(),
    };

    setChartData(data); // use state
}, [applicableChannels]);

useBus(
    '@@charts/INTERACT',
    (data) => {
        const payload = data.payload;

        if (payload.sender === chartRef.current.id) {
            return;
        }

        // update chart scale/zoom/pan to be in sync with all others
        chartRef.current.options.scales.x.min = payload.x.min;
        chartRef.current.options.scales.x.max = payload.x.max;

        chartRef.current.update();
    },
    [],
);

return (

      <Chart type={"line"} ref={chartRef} options={chartOptions} data={chartData} />
);

如您在配置中所见,我放置了两个 alert 以在事件触发时通知我。 "I am zooming!" 被完美触发,但 "I am panning!" 从未被触发。也不是任何其他泛特定事件。

这是一个很奇怪的问题。任何帮助,将不胜感激! 谢谢!

当你使用useEffect(()=>{},[xxx])钩子时,第二个参数是[xxx],你应该知道只有当xxx发生变化时,它才会运行函数。在你的情况下,我在你的代码中没有看到任何“applicableChannels”,所以很难知道问题出在哪里。

问题已解决。

初始化图表时,HammerJS 会初始化并将 panning/zooming 的侦听器添加到 canvas。当在创建配置之前使用配置初始化图表(将配置设置为空状态),以及更新实际配置(使用 zoom/pan 插件)时,[=10 的状态=] 中的平移对象未正确更新,因此平移被禁用。

解决方案是等待显示图表 React 元素,直到配置可用于填充它。

这个问题确实发生了,因为配置是在 useEffect 挂钩中设置的,使其在比创建实际 JSX 元素更晚的事件循环滴答中可用。