apache / apache/echarts

[Bug] Cannot read properties of undefined (reading 'group') in blurSeries during React re-render

Open
#21,559 0 comments 0 reactions 0 assignees View on GitHub
en pending
Dominant language
TypeScript
Stars
67.3k
Forks
19.8k
Avg merge
11d 14h
Merged PRs (30d)
8

Description

### Version

6.0.0

### Link to Minimal Reproduction

N/A — race condition during React component re-render

### Steps to Reproduce

1. Render an ECharts chart (Sankey, Bar, Treemap) inside a React component
2. Use `notMerge: true` with `echarts-for-react`
3. Trigger a data change that causes React to re-render the chart (e.g., toggling filter buttons)
4. While the chart is re-rendering, move the mouse over the chart area

### Current Behavior

Runtime TypeError:

```
Cannot read properties of undefined (reading 'group')
```

**Stack trace:**

```
blurSeries (echarts/lib/util/states.js:362)
→ var view = api.getViewOfSeriesModel(seriesModel);
→ view.group.traverse(...) // 💥 view is undefined

handleGlobalMouseOverForHighDown (states.js:499)
Handler. (echarts.js:1549)
Eventful.trigger (zrender/Eventful.js:103)
Handler.dispatchToElement (zrender/Handler.js:148)
Handler.mousemove (zrender/Handler.js:101)
HandlerDomProxy.mousemove (zrender/HandlerProxy.js:90)
HTMLDivElement. (zrender/HandlerProxy.js:209)
```

### Expected Behavior

No crash. The blur effect should be skipped gracefully when the series view has been disposed.

### Root Cause

In `blurSeries()` (`src/util/states.ts`), `api.getViewOfSeriesModel(seriesModel)` can return `undefined` when a series model still exists in the `GlobalModel` but its view has been disposed during a React re-render cycle (via `setOption` with `notMerge` or component unmount). The code unconditionally accesses `view.group`:

```typescript
const view = api.getViewOfSeriesModel(seriesModel);
view.group.traverse(function (child) { // ← crashes if view is undefined
```

This is the same class of bug as #9402 and #21535 — stale references to disposed series during mouse events.

### Suggested Fix

Add a null guard after the view lookup:

```typescript
const view = api.getViewOfSeriesModel(seriesModel);
if (!view || !view.group) {
return;
}
view.group.traverse(function (child) {
```

This follows the same pattern used elsewhere in the codebase (e.g., `toggleSeriesBlurState` already guards `view` access).

I will submit a PR with this fix.

### Environment

| Item | Value |
|------|-------|
| OS | macOS |
| Browser | Chrome |
| Framework | React 19 + Next.js 16 |
| echarts-for-react | 3.0.6 |

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.