mui / mui-x

MUI X: Build complex and data-rich applications using a growing list of advanced React components, like the Data Grid, Date and Time Pickers, Charts, and more!
https://mui.com/x/
4.56k stars 1.33k forks source link

Uncaught TypeError: Cannot set properties of null (setting 'scrollTop') #14987

Closed theodoremoreland closed 3 weeks ago

theodoremoreland commented 1 month ago

Link to live example: https://theodoremoreland.github.io/mui-x-data-grid-bug-demo/ The code can be found here: https://github.com/theodoremoreland/mui-x-data-grid-bug-demo/tree/updated-package-versions

This bug was actually discovered and reported by another person prior, but the thread was closed temporarily: https://github.com/mui/mui-x/issues/13301

The bug

When scrolling to the very bottom of the virtual scrollbar using a scroll wheel then decreasing the number of rows in a Data Grid via clicking a lesser page option or via programmatically deleting rows via some custom UI prompt (such as a Delete button) such that the vertical, virtual scroll bar is no longer needed, the Data Grid will throw the following error on Chrome:

Cannot set properties of null (setting 'scrollTop')
TypeError: Cannot set properties of null (setting 'scrollTop')
    at http://localhost:3000/static/js/bundle.js:49775:31
    at HTMLDivElement.<anonymous> (http://localhost:3000/static/js/bundle.js:37491:19)

The following error on Firefox:

scrollbar is null
./node_modules/@mui/x-data-grid/components/virtualization/GridVirtualScrollbar.js/GridVirtualScrollbar/onScrollerScroll<@http://localhost:3000/static/js/bundle.js:49775:41
./node_modules/@mui/utils/esm/useEventCallback/useEventCallback.js/useEventCallback/<@http://localhost:3000/static/js/bundle.js:37491:19

OR

Uncaught TypeError: t is null
    g GridVirtualScrollbar.js:82
    Gs useEventCallback.js:18

NOTE: Reproducing the error via programmatic deletion is inconsistent on Firefox (in my experience). However, the error occurs consistently in Chrome and in both browsers via decreasing page option.

Steps to reproduce

The conditions to reproduce the bug are very conditional, if not inconsistent. For example, from what I can tell:

Use case 1

NOTE: Oddly enough, scrolling to the bottom of the grid / virtual scrollbar by clicking and dragging the scroll bar down does not produce an error nor does scrolling close to the bottom. The error is only produced by scrolling to the absolute bottom of the scrollbar via scroll wheel in this example.

  1. Open app in either Chrome or Firefox web browser
  2. Click OPEN button to open Drawer component featuring two Data Grids
  3. Click Grid 2 tab
  4. Scroll to the absolute bottom of the data grid using scroll wheel (not by dragging scroll bar down with mouse)
  5. Change Rows per page option to 2 instead of 100

If running the code locally, you should see an error popup in the UI. If running a deployed build, you may only see the error in the dev console.

Screenshots 1

Use case 2

NOTE: Weirdly enough, the following steps produce an error far more often when using Google Chrome, in my experience. It may take multiple attempts to get the error to produce in Firefox if at all.

  1. Open app in either Chrome or Firefox web browser
  2. Click OPEN button to open Drawer component featuring two Data Grids
  3. Click Grid 2 tab
  4. Scroll to the absolute bottom of the data grid using scroll wheel (not by dragging scroll bar down with mouse)
  5. Click the DELETE button (top right, just above Data Grid)

If running the code locally, you should see an error popup in the UI. If running a deployed build, you may only see the error in the dev console.

Screenshots 2

A potential workaround

For some reason, how you render React's root DOM node can circumvent the error. For example, given "react": "^18.3.1" and "react-dom": "^18.3.1":

This does not work:

import React from "react";
import ReactDOM from "react-dom"; // ? This version of ReactDOM causes error
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById("root") as HTMLElement
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

This does:

import React from 'react';
import ReactDOM from 'react-dom/client'; // ? This version of ReactDOM does not cause error
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

const root = ReactDOM.createRoot(
  document.getElementById("root") as HTMLElement
);
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

Current behavior

An error appears in the UI and in the dev console.

Expected behavior

Same functionality but without error message.

Context

I am trying to scroll to the bottom of the grid then proceed to decrease the number of rows displayed either via programmatic deletion or decreasing page options.

Your environment

npx @mui/envinfo I have test Chrome and Firefox. ``` System: OS: Windows 11 10.0.22631 Binaries: Node: 22.8.0 - C:\Program Files\nodejs\node.EXE npm: 10.8.2 - C:\Program Files\nodejs\npm.CMD pnpm: Not Found Browsers: Chrome: Not Found Edge: Chromium (127.0.2651.74) npmPackages: @emotion/react: ^11.13.3 => 11.13.3 @emotion/styled: ^11.13.0 => 11.13.0 @mui/core-downloads-tracker: 6.1.3 @mui/icons-material: ^6.1.3 => 6.1.3 @mui/material: ^6.1.3 => 6.1.3 @mui/styled-engine: 6.1.3 @mui/system: 6.1.3 @mui/types: 7.2.18 @mui/utils: 5.16.6 @mui/x-data-grid: ^7.20.0 => 7.20.0 @mui/x-internals: 7.20.0 @types/react: ^18.3.11 => 18.3.11 react: ^18.3.1 => 18.3.1 react-dom: ^18.3.1 => 18.3.1 typescript: ^4.9.5 => 4.9.5 ```

Search keywords: GridVirtualScrollbar data grid null scrolltop scroll

MBilalShafi commented 1 month ago

Thank you @theodoremoreland for the reproduction and detailed reproduction steps. I was able to drill down the reproduction to https://codesandbox.io/p/sandbox/vigilant-dijkstra-nj43jm

When the Data Grid is rendered in a Drawer and it is scrolled beyond screen. If we set the page size in a way that scroll disappears, it clears the scrollbarRef for some reason which results in the displayed error.

I tried to fix it in #15009 and a codesandbox generated from it seems to not have the problem anymore: https://codesandbox.io/p/sandbox/snowy-river-2skv9t

@mui/xgrid Yet another culprit of !. I think we should try to add extra checks instead of ! especially at those places which refer to external entities like DOM events that could be tinkered with by an external script.

github-actions[bot] commented 3 weeks ago

This issue has been closed. If you have a similar problem but not exactly the same, please open a new issue. Now, if you have additional information related to this issue or things that could help future readers, feel free to leave a comment.

[!NOTE] @theodoremoreland How did we do? Your experience with our support team matters to us. If you have a moment, please share your thoughts in this short Support Satisfaction survey.

giavinh79 commented 6 days ago

Thank you @theodoremoreland for the reproduction and detailed reproduction steps. I was able to drill down the reproduction to https://codesandbox.io/p/sandbox/vigilant-dijkstra-nj43jm

When the Data Grid is rendered in a Drawer and it is scrolled beyond screen. If we set the page size in a way that scroll disappears, it clears the scrollbarRef for some reason which results in the displayed error.

I tried to fix it in #15009 and a codesandbox generated from it seems to not have the problem anymore: https://codesandbox.io/p/sandbox/snowy-river-2skv9t

@mui/xgrid Yet another culprit of !. I think we should try to add extra checks instead of ! especially at those places which refer to external entities like DOM events that could be tinkered with by an external script.

I am seeing a related error which is Cannot read properties of null (reading 'scrollTop') coming from useGridVirtualScroller. The error is quite intermittent since it comes from a setTimeout and I am still trying to find a good way to create a good reproduction sandbox of this issue.

For more context, the error happens in my app after scrolling the data grid and then navigating quickly after so that the component unmounts/is destroyed. Tested this in the latest version of "@mui/x-data-grid-premium" and in Chrome.

image
cherniavskii commented 6 days ago

@giavinh79 I tried reproducing this issue, but no luck: https://codesandbox.io/p/sandbox/affectionate-brook-qprvq4 I've opened https://github.com/mui/mui-x/pull/15521 to fix it anyway.