[Bug] Cannot read properties of undefined (reading 'group') in blurSeries during React re-render
- 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
Assessment
This issue has not been assessed yet.