how to display a value other than the renderValue in material ui select

Viewed 15989

I have a dropwdown that has to display the flags of 3 countries and I have to choose one. But the dropdown logic works differently depending on the renderValue. I have 3 different cases :

Case 1

renderValue={value => <img src={value.country[0]} alt="RenderValue" />}

the flag of the renderValue is displayed but if you try to choose another value you have an error:

The above error occurred in the <ForwardRef(SelectInput)> component: (...)
Consider adding an error boundary to your tree to customize error handling behavior.

Case 2

renderValue={value => <img src={value[0]} alt="RenderValue" />}

the flag of the renderValue does not appear and if you try to choose another value it keeps displaying the RenderValue


Case 3

The renderValue is removed 

Everything works but we have more rendervalue


Here is the select : https://codesandbox.io/s/reverent-fermat-zssow?fontsize=14

you can play with all three cases. Case 3 is the default case :)

I want the select to work with a renderValue I don't know what I'm doing wrong

1 Answers

It is unclear to me what you were trying to achieve with the renderValue function. This is only useful if you want the selected value to look different than the corresponding MenuItem, but the content you had in the renderValue appeared to have the same intent as the MenuItem (show the flag image).

The main thing I changed to get things showing properly is to leverage the imported flag images when constructing the countries array and I fixed the initialization of the country state to be one of the valid values (rather than an object with an array of all the values).

If you still think you need to use renderValue, please clarify what you want to be rendered differently about the selected value vs. how it displays when the Select is open.

Here's my modified version of your sandbox:

import React from "react";
import ReactDOM from "react-dom";

import { makeStyles } from "@material-ui/core/styles";
import InputLabel from "@material-ui/core/InputLabel";
import MenuItem from "@material-ui/core/MenuItem";
import FormControl from "@material-ui/core/FormControl";
import Select from "@material-ui/core/Select";
import France from "./assets/flags/france.png";
import Allemagne from "./assets/flags/germany.png";
import Suisse from "./assets/flags/switzerland.png";

const countries = [
  {
    label: "France",
    src: France,
    link: " ",
    value: "FR"
  },
  {
    label: "Allemagne",
    src: Allemagne,
    link: " ",
    value: "DE"
  },
  {
    label: "Suisse",
    src: Suisse,
    link: " ",
    value: "CH"
  }
];

const useStyles = makeStyles(theme => ({
  button: {
    display: "block",
    marginTop: theme.spacing(2)
  },
  formControl: {
    margin: theme.spacing(5),
    minWidth: 120,
    backgroundColor: "transparent"
  },
  select: {
    textAlign: "center",
    textDecoration: "none"
  }
}));
function App() {
  const classes = useStyles();
  const [country, setCountry] = React.useState(France);
  const [open, setOpen] = React.useState(false);

  const handleChange = event => {
    setCountry(event.target.value);
  };

  const handleClose = () => {
    setOpen(false);
  };

  const handleOpen = () => {
    setOpen(true);
  };

  return (
    <form autoComplete="off">
      <FormControl className={classes.formControl}>
        <InputLabel htmlFor="open-select" />
        <Select
          open={open}
          onClose={handleClose}
          onOpen={handleOpen}
          value={country}
          name="country"
          onChange={handleChange}
          inputProps={{
            id: "open-select"
          }}
        >
          {countries.map((option, key) => (
            <MenuItem value={option.src} key={key}>
              <img src={option.src} alt={option.label} />{" "}
            </MenuItem>
          ))}
        </Select>
      </FormControl>
    </form>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Edit Country/Flag Select

Related