Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BP.Table scroll events are processed after table gets unmounted #4472

Closed
N1kto opened this issue Jan 7, 2021 · 3 comments
Closed

BP.Table scroll events are processed after table gets unmounted #4472

N1kto opened this issue Jan 7, 2021 · 3 comments

Comments

@N1kto
Copy link

N1kto commented Jan 7, 2021

Environment

  • Package version(s): @blueprintjs/table@3.8.18 (and 3.8.13)
  • Operating System: Linux
  • Browser name and version: Chromium 87, Firefox 86

Code Sandbox

Link to a minimal repro (fork this code sandbox): https://codesandbox.io/s/blueprint-sandbox-forked-iuzkh

Steps to reproduce

  1. Go to table
  2. Scroll the table back and forth
  3. Click the "go back" button quickly after the scroll (in real environment, clicking the back button to navigate to the previous location works the same)

Actual behavior

Exception is thrown: TypeError: Cannot read property 'offsetWidth' of null

bp.table.mp4

Expected behavior

No exception

Possible solution

The scroll event handler should check if the table is still mounted

@N1kto
Copy link
Author

N1kto commented Feb 1, 2022

For those still suffering because of this issue I've come up with a workaround.

  1. You need a BP.Table reference
import { Table } from  '@blueprintjs/table';
import { useRef } from ''react';
const SomeFancyTable = (fancyTableProps) => {
  const tableRef = useRef<null | Table>(null);
  ...
  return (
    <Table ref={rableRef} {...fancyTableProps} />
  );
}
  1. Add an unmount handler to your component where you'd manually clear debouncedViewSyncInterval. Clearing this interval fixes the issue:
useEffect(() => {
      // ensure any scheduled handlers are canceled on unmount
      return () => {
        if (tableRef.current) {
          // dispite quadrantStackInstance being a private member of quadrantStackInstance we still can access it
          const tableQuadrantStackInstance = (tableRef.current as any).quadrantStackInstance;
          clearInterval(tableQuadrantStackInstance?.debouncedViewSyncInterval);
          // also added these 2 `clearTimeouts` calls below (they don't help with original issue though), as it still feels right to call them on unmount
          tableQuadrantStackInstance?.clearTimeouts();
          tableRef.current.clearTimeouts();
        }
      };
    }, []);

@adidahiya
Copy link
Contributor

@N1kto we have some share component infra for dealing with canceling timeouts on unmount. I've gone ahead and used that here in #5124. That should fix the issue, but beware that it will break your workaround because of a private member rename.

@adidahiya adidahiya self-assigned this Feb 10, 2022
@adidahiya adidahiya added this to the 4.0.0 milestone Feb 10, 2022
@adidahiya
Copy link
Contributor

Fixed in v4 by #5124. If there's a strong need for a backport to v3, I'll consider it, but for now I'm trying to only push new code to v4.

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants