hayaoki hayane
hayaoki hayane

Reputation: 33

Material-UI how to use forwardRef in MenuItem

If you return MenuItem in Array.map, error occur when I press Select.

Code

const MenuItems: React.FC<{ items: number[] }> = (props) => {
  const { items } = props;
  return (
    <>
      {items.map((i) => {
        return (
          <MenuItem key={i} value={i}>
            {i}
          </MenuItem>
        );
      })}
    </>
  );
};

Error

Warning: Function components cannot be given refs. Attempts to access this ref will fail.
Did you mean to use React.forwardRef()?

So I want to rewrite it to forwardRef, but I don't know the type of ref. Is it possible to use forwardRef for MenuItem in the first place?

Thank you.

Upvotes: 2

Views: 2253

Answers (1)

Linda Paiste
Linda Paiste

Reputation: 42298

Problem: Separation between Select and MenuItem

The Material UI Select component expects to have MenuItem components as its direct children. It will pass a ref to its children. In your case, the child of the the Select would be your MenuItems component, which doesn't accept a ref. I don't recommend ref forwarding here. Instead, you need to redesign your component structure so that there is no separation between the Select and the mapped MenuItem.

Here's one example:

import { MenuItem, Select, SelectProps } from "@material-ui/core";
import React, { useState } from "react";

type MyMenuProps = {
  items: number[];
  value: number;
} & Pick<SelectProps, "onChange">;

const MyMenu: React.FC<MyMenuProps> = (props) => {
  const { items, value, onChange } = props;
  return (
    <Select value={value} onChange={onChange}>
      {items.map((i) => {
        return (
          <MenuItem key={i} value={i}>
            {i}
          </MenuItem>
        );
      })}
    </Select>
  );
};

export default function App() {
  const [value, setValue] = useState(1);
  return (
    <MyMenu
      value={value}
      onChange={(e) => setValue(parseInt(e.target.value))}
      items={[1, 2, 3, 4]}
    />
  );
}

Upvotes: 2

Related Questions