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

[data grid] Possible bug in useGridApiRef after upgrade to v7.23.6 #16135

Closed
doberkofler opened this issue Jan 11, 2025 · 16 comments · Fixed by #16279
Closed

[data grid] Possible bug in useGridApiRef after upgrade to v7.23.6 #16135

doberkofler opened this issue Jan 11, 2025 · 16 comments · Fixed by #16279
Assignees
Labels
bug 🐛 Something doesn't work component: data grid This is the name of the generic UI component, not the React module! typescript

Comments

@doberkofler
Copy link

doberkofler commented Jan 11, 2025

Steps to reproduce

Up until 7.23.5, the useGridApiRef hook return an object with the current property of type GridApi but with 7.23.5 the property can also be null and therefore code like the following can no longer be compiled using TypeScript.

const apiRef = useGridApiRef();
const row = apiRef.current.getRow<Record<string, unknown>>(params.id);

Current behavior

error TS18047: 'apiRef.current' is possibly 'null'.

Expected behavior

apiRef.current to be of type GridApi

Context

No response

Your environment

npx @mui/envinfo
System:
    OS: macOS 15.2
  Binaries:
    Node: 22.12.0 - ~/.nvm/versions/node/v22.12.0/bin/node
    npm: 11.0.0 - ~/.nvm/versions/node/v22.12.0/bin/npm
    pnpm: 9.5.0 - ~/.nvm/versions/node/v22.12.0/bin/pnpm
  Browsers:
    Chrome: 131.0.6778.265
    Edge: Not Found
    Safari: 18.2
  npmPackages:
    @emotion/react: 11.14.0 => 11.14.0 
    @emotion/styled: 11.14.0 => 11.14.0 
    @mui/core-downloads-tracker:  6.3.1 
    @mui/icons-material: 6.3.1 => 6.3.1 
    @mui/material: 6.3.1 => 6.3.1 
    @mui/private-theming:  6.3.1 
    @mui/styled-engine:  6.3.1 
    @mui/system:  6.3.1 
    @mui/types:  7.2.21 
    @mui/utils:  6.3.1 
    @mui/x-data-grid: 7.23.6 => 7.23.6 
    @mui/x-internals:  7.23.6 
    @types/react: 18.3.13 => 18.3.13 
    react: 18.3.1 => 18.3.1 
    react-dom: 18.3.1 => 18.3.1 
    typescript: 5.7.3 => 5.7.3 

Search keywords: useGridApiRef typescript current

@doberkofler doberkofler added bug 🐛 Something doesn't work status: waiting for maintainer These issues haven't been looked at yet by a maintainer labels Jan 11, 2025
@github-actions github-actions bot added the component: data grid This is the name of the generic UI component, not the React module! label Jan 11, 2025
@GiuntaLucas
Copy link

Hello,

The problem is the hook useGridApiRef is returning the wrong type. It returning the React.RefObject<DataGridPro> instead of React.MutableRefObject<DataGridPro>. All our code base started to break couple of days ago. The rollback to the previous version should fix this issue for now.

Waiting some update from MUI before to go back to the latest version.

@michelengelen
Copy link
Member

Related issues: #16116, #16000

@arminmeh this came up after the last release. Could you have a look please?

@github-project-automation github-project-automation bot moved this to 🆕 Needs refinement in MUI X Data Grid Jan 13, 2025
@michelengelen michelengelen removed the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label Jan 13, 2025
@michelengelen michelengelen changed the title Possible bug in useGridApiRef after upgrade to 7.23.6 [data grid] Possible bug in useGridApiRef after upgrade to v7.23.6 Jan 13, 2025
@arminmeh
Copy link
Contributor

Hi @doberkofler

The new behavior is actually the correct one.
You can check use case from #16000 where the apiRef can actually be null.

Still, the team has decided that we will revert this back for v7 and mention this as a breaking change in the migration notes for v8 because it can create a lot of burden for the current users of v7.

@GiuntaLucas we will also make sure that apiRef is reverted to be MutableRefObject for React versions < 19

@arminmeh arminmeh moved this from 🆕 Needs refinement to 🔖 Ready in MUI X Data Grid Jan 14, 2025
@doberkofler
Copy link
Author

Hi @arminmeh

I personally have no problem with breaking changes as long as they are documented and I understand what needs to be adapted but understand why the team decided to revert this change.

Did I understand correctly that the code would need to make sure current is not null every time the reference is used?

const apiRef = useGridApiRef();
const row = apiRef.current ? apiRef.current.getRow<Record<string, unknown>>(params.id) : null;

Thank you!

@michelengelen
Copy link
Member

Hi @arminmeh

I personally have no problem with breaking changes as long as they are documented and I understand what needs to be adapted but understand why the team decided to revert this change.

Did I understand correctly that the code would need to make sure current is not null every time the reference is used?

const apiRef = useGridApiRef();
const row = apiRef.current ? apiRef.current.getRow<Record<string, unknown>>(params.id) : null;
Thank you!

Yes, you would have to check that for null.

Correct me if I am wrong @arminmeh, but we still need to check for null, but with v8 there will no longer be an empty object before initialization, right?

So, the main difference would be that we can drop the second check:

-apiRef.current?.getRow?.()
+apiRef.current?.getRow()

@doberkofler in your case you could also shorten the codeblock to this:

const apiRef = useGridApiRef();
const row = apiRef.current?.getRow<Record<string, unknown>>?.(rowId) || null;

@TheMoonDawg
Copy link

The documentation is also incorrect with this type change: https://mui.com/x/react-data-grid/row-grouping/#hide-the-grouped-columns

I'm trying to do this for example and getting a type error:

  const apiRef = useGridApiRef()

  const initialState = useKeepGroupedColumnsHidden({
    apiRef,
    initialState: {
      columns: {
        columnVisibilityModel: {
          dueDate: false,
          actioned: false,
          pharmacy: false,
        },
      },
    },
  })

Image

@arminmeh
Copy link
Contributor

Correct me if I am wrong @arminmeh, but we still need to check for null

@michelengelen
Agreement is that we will not correct the type for v7, to avoid having CI builds broken.

@arminmeh arminmeh self-assigned this Jan 16, 2025
@arminmeh arminmeh moved this from 🔖 Ready to 🏗 In progress in MUI X Data Grid Jan 16, 2025
@arminmeh
Copy link
Contributor

Just to update everyone

Fix for the type mismatch is merged and should be released by the end of the week.
All references will be RefObject which means that the original issue raised (null possibility) still remains.

As mentioned before, I am working on having this reverted back to MutableRefObject for React < 19.

@sternma
Copy link

sternma commented Jan 16, 2025

Thank you @arminmeh !

@doberkofler
Copy link
Author

I'm trying to understand how to safely use the API in 7.23.6 but am still a little confused.
My interface for using the Grid API looks something the following and I've now added if (!apiRef.current) {throw new Error("Internal error");} to the useLayoutEffect callback but TypeScript still complains about a type error when using the apiRef={apiRef} property. What am I missing?

import React from "react";
import { useLayoutEffect } from "react";
import { createRoot } from "react-dom/client";
import { DataGridPro, useGridApiRef, type GridApi } from "@mui/x-data-grid-pro";

export type apiRefType = React.MutableRefObject<GridApi>;

type GridPropsType = {
  readonly updateApiRef: (ref: apiRefType) => void;
};

const Grid = ({ updateApiRef }: GridPropsType) => {
  const apiRef = useGridApiRef();

  useLayoutEffect(() => {
    if (!apiRef.current) {
      throw new Error("Internal error");
    }
    updateApiRef(apiRef as apiRefType);
  }, [updateApiRef, apiRef]);

  return (
    <div style={{ height: "100%", width: "100%" }}>
      <DataGridPro apiRef={apiRef} columns={[]} rows={[]} />
    </div>
  );
};

type renderGridType = {
  container: HTMLElement;
};

export const renderGrid = async (
  options: renderGridType
): Promise<apiRefType> => {
  return new Promise((resolve) => {
    createRoot(options.container).render(<Grid updateApiRef={resolve} />);
  });
};

@arminmeh
Copy link
Contributor

@doberkofler does the upgrade to 7.24.0 solve the problem for your code snippet?

@doberkofler
Copy link
Author

@arminmeh Yes, with 7.24.0 my code snipped works. Does my use of useGridApiRef show how it was indented to be used in the future?

@arminmeh
Copy link
Contributor

Does my use of useGridApiRef show how it was indented to be used in the future?

Yes useGridApiRef is from 7.24.0 returning the same type that is needed for apiRef prop.
Additionally, this PR will revert that type back to MutableRefObject for react versions prior to 19, which will allow your original code to run just fine and you will not have the need to cast the ref apiRef as apiRefType

From version 8 onwards, you will have to use the check from the snippet since the ref can be null in certain cases and we want to have this explicitly stated in the type.

@arminmeh arminmeh moved this from 🏗 In progress to 👀 In review in MUI X Data Grid Jan 23, 2025
Copy link

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

@doberkofler 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.

@arminmeh arminmeh moved this from 👀 In review to ✅ Done in MUI X Data Grid Jan 24, 2025
@doberkofler
Copy link
Author

@arminmeh The problem seems to have reappeared after upgrading to 7.24.1

@arminmeh
Copy link
Contributor

@doberkofler

In 7.24.1 we have released my update for the types which should have resulted in this matrix.

Unfortunately, one small issue remained which is causing problems for Pro and Premium packages in combination with React 18.

I have already opened a PR with the fix. It should land in the next week's release.

As mentioned in the comment

In the meantime, feel free to cast the return type from the useGridApiRef hook to React.MutableRefObject if you are on React 18 and using Pro or Premium package.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 🐛 Something doesn't work component: data grid This is the name of the generic UI component, not the React module! typescript
Projects
Status: Done
Development

Successfully merging a pull request may close this issue.

6 participants