shunyun
shunyun

Reputation: 31

How to create a custom Material UI DataGrid column menu item?

For Material UI's DataGrid (v5.2.0), I am trying to create a custom column menu item to act on the column. If I set onClick={hideMenu} then the menu successfully hides when I click it. However, if I set onClick={handleMenuItemClick}, and in that function call hideMenu(), then I get an uncaught error, complaining about stopPropagation. This makes me think that I'm successfully accessing hideMenu() but the reference is wrong.

So my question is:

  1. How do I correctly pass reference so that I can call/reference hideMenu and currentColumn?

  2. (Extra Credit) Once I get that reference right, how do I mutate the data grid, such as deleting/adding/renaming columns? Do I have to pass apiRef (eg useGridApiRef() ) or is the reference to currentColumn enough?

Uncaught TypeError: Cannot read properties of undefined (reading 'stopPropagation') at index-esm.js:15:1 at handleMenuItemClick (CustomColumnMenuComponent.jsx:17:1) at HTMLUnknownElement.callCallback (react-dom.development.js:3945:1) at Object.invokeGuardedCallbackDev (react-dom.development.js:3994:1) at invokeGuardedCallback (react-dom.development.js:4056:1) at invokeGuardedCallbackAndCatchFirstError (react-dom.development.js:4070:1) at executeDispatch (react-dom.development.js:8243:1) at processDispatchQueueItemsInOrder (react-dom.development.js:8275:1) at processDispatchQueue (react-dom.development.js:8288:1) at dispatchEventsForPlugins (react-dom.development.js:8299:1)

import * as React from 'react';
import MenuItem from '@mui/material/MenuItem';
import {
  GridColumnMenuContainer,
} from '@mui/x-data-grid-pro';

export default function CustomColumnMenuComponent(props) {
  const { hideMenu, currentColumn, ...other } = props;

  const handleMenuItemClick = () => {
    // do something with currentColumn...
    hideMenu()
  };

  return (
    <GridColumnMenuContainer hideMenu={hideMenu} currentColumn={currentColumn} {...other}>
      <MenuItem onClick={handleMenuItemClick} column={currentColumn}>Mutate Column</MenuItem>
      <MenuItem onClick={hideMenu} column={currentColumn}>Close Menu</MenuItem>
    </GridColumnMenuContainer>
  );
};

Upvotes: 3

Views: 3788

Answers (1)

paul
paul

Reputation: 1142

You must pass the the original event to hideMenu as an argument when wrapping it with a higher-order handler. The original event is supplied by MUI with onClick.

  const handleMenuItemClick = (event) => {
    // do something with currentColumn...
    hideMenu(event)
  };

The first example is working for you because the event passing happens automatically when hideMenu is supplied directly as the onClick handler.

Your second question is a little vague, maybe clarify exactly what you want to do. But in general, you can get access to the API methods inside your custom component like this:

const apiRef = useGridApiContext();

and the guide for using the api reference and the available methods are documented here https://mui.com/x/react-data-grid/api-object/

Upvotes: 2

Related Questions