简体   繁体   中英

Material UI Select Component with database data

I am trying to populate a select component from Material UI with data from my database. I can successfully show the data in the component, but when I select one option it breaks and the following error "categorias.map is not a function" shows up. Does anybody know what am I doing wrong? Here is the code:

<FormControl className={classes.formControl}>
  <InputLabel id="demo-simple-select-label">Categorias</InputLabel>
    <Select
      labelId="demo-simple-select-filled-label"
      id="demo-simple-select-filled"
      value={categorias}
      onChange={(ev) => setCategorias(ev.target.value)}
    >
      <MenuItem value="">
        <em>None</em>
      </MenuItem>
      {categorias.map((categoria) =>
        <MenuItem value={categoria.id}>{categoria.nombre}</MenuItem>
      )}
    </Select>
</FormControl>

Here is more code regarding categorias:

const [categorias, setCategorias] = useState([]);


  useEffect(() => {

      const getCategorias = async () => {
        const res = await fetch("/categories", {
            method: 'GET',
            headers: {'Content-Type': 'application/json'},
        })
        //console.log(res);
        const response = await res.json();
        setCategorias(response);
        console.log(categorias);
      }
      getCategorias();
  })

Thank you!

One of the common causes could be categorias might be not have a default value ie undefined before the rest call completes.

if you give the variable a default value like '[]' it might solve your problem. Or,if you are using es2020, you could try categorias?.map(...)

I think it would be helpful if you can show the code leading up to the render to help us understand the problem better.

update: based on useEffects code, you might want to check your endpoint to ensure it's returning an array of objects for you

What type is categorias? .map is a built-in method of the arrays prototype. If categories is no an array, that could be your problem. I'm guessing you're in react, so try console logging categories out to see what it is at run.

You could try this:

<MenuItem value="">
    <em>None</em>
</MenuItem>
{categorias & categorias.map((categoria) =>
    <MenuItem value={categoria.id}>{categoria.nombre}</MenuItem>
)}

The issue is that you is that you are replacing your array of categorias with an object with the onChange event, which then means that categorias is no longer an array so it cant use.map which is why you are getting an error

What you need to do is create another state to hold the selected value

import React, { useState, useEffect } from "react";
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";

const useStyles = makeStyles((theme) => ({
  formControl: {
    margin: theme.spacing(1),
    minWidth: 120
  }
}));

export default function SimpleSelect() {
  const classes = useStyles();
  const [categorias, setCategorias] = useState([]);
  const [selectedCategorias, setselectedCategorias] = useState("");

  useEffect(() => {
    const getCategorias = async () => {
      const res = await fetch("/categories", {
        method: "GET",
        headers: { "Content-Type": "application/json" }
      });
      //console.log(res);
      const response = await res.json();
      setCategorias(response);
    };
    getCategorias();
  }, []);

  return (
    <FormControl className={classes.formControl}>
      <InputLabel id="demo-simple-select-label">Categorias</InputLabel>
      <Select
        labelId="demo-simple-select-filled-label"
        id="demo-simple-select-filled"
        value={selectedCategorias}
        onChange={(ev) => setselectedCategorias(ev.target.value)}
      >
        <MenuItem value="">
          <em>None</em>
        </MenuItem>
        {categorias.map((categoria) => (
          <MenuItem key={categoria.id} value={categoria.id}>{categoria.nombre}</MenuItem>
        ))}
      </Select>
    </FormControl>
  );
}

Another couple of issues I found is you are missing the key prop in the MenuItem, and in your useEffect you don't have any dependencies so it will run in an infinite loop. So I have included it so it only runs on mount.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM