react-echarts icon indicating copy to clipboard operation
react-echarts copied to clipboard

Bug: ZRender event handlers not working properly after update (1.4.0 > 1.4.2)

Open brunodesde1987 opened this issue 10 months ago • 2 comments

Description

After updating from 1.4.0 to the latest version (1.4.2), attaching event handlers directly to the ZRender instance using getZr() throws an error when trying to cleanup on unmount.

Previous Behavior

useEffect(() => {
    echartsInstance?.getZr().on('mousedown', () => {
     console.log('=> mousedown')
    })

    return () => {
      echartsInstance?.getZr().off('mousedown')
    }
}, [echartsInstance])

This code worked as expected.

Current Behavior

Now throws error:

Uncaught TypeError: Cannot read properties of null(reading 'off')

Root Cause

This might be related to the new event cleanup implementation in event-handlers.ts, causing the ZRender instance to become temporarily invalid during the cleanup phase.

Solution

While the previous implementation worked on the version 1.4.0, a more defensive approach should be used by storing and validating the ZRender reference before using it:

useEffect(() => {
    const zr = echartsInstance?.getZr()
    if (!zr) return
    
    zr.on('mousedown', () => setShowTooltip(true))
    return () => zr.off('mousedown')
}, [echartsInstance])

Link to Reproduction

https://stackblitz.com/edit/vitejs-vite-fndic4en?file=src%2Fcomponents%2FChart.tsx

Steps to reproduce

  1. Navigate to a page with the ECharts component
  2. Navigate away from this page
  3. You will see a blank page (Check the console for the error)

JS Framework

React (TS)

Version

1.4.2

Browser

Google Chrome 132.0.6834.160

Operating System

  • [x] macOS
  • [ ] Windows
  • [ ] Linux

Additional Information

This might not be considered an actual bug but I wanted to share it anyway so that if anybody goes through the same issue they will have a solution.

brunodesde1987 avatar Feb 19 '25 15:02 brunodesde1987

edit: Ha, I just realised my comment is just a repeat of what you already wrote. So, re-fetching ZRender was working previously, but has regressed?

(my original comment follows)


This seems to be related to attempting to fetch the instance of ZRender again after the component is unmounted. I was able to get the code working by just storing the instance in a const:

import { useEffect } from 'react';
import { useECharts } from '@kbox-labs/react-echarts';
import { options } from '../chartOptions';

export const Chart = () => {
  const [containerRef, echartsInstance] = useECharts<HTMLDivElement>({
    ...options,
  });

  useEffect(() => {
    if (!echartsInstance) return;
    const zRender = echartsInstance.getZr();

    zRender.on('mousedown', () => {
      console.log('=> mousedown 🙃');
    });

    return () => {
      zRender.off('mousedown');
    };
  }, [echartsInstance]);

  return <div ref={containerRef} style={{ height: '400px', width: '100%' }} />;
};

MiracleBlue avatar Feb 22 '25 02:02 MiracleBlue

edit: Ha, I just realised my comment is just a repeat of what you already wrote. So, re-fetching ZRender was working previously, but has regressed?

Correct. As I mentioned above, I got it working after storing the instance, but it broke my application after the update, so I thought a good idea to raise this issue anyway so that if anybody goes through the same problem they will have a solution.

brunodesde1987 avatar Mar 11 '25 13:03 brunodesde1987