简体   繁体   English

使用对象数组作为源来反应 Material-UI Select

[英]React Material-UI Select using an array of objects as the source

Hoping I can get some help.希望我能得到一些帮助。 I'm currently following a tutorial that is using React Material-UI, specifically to do with a simple Select drop-down.我目前正在关注使用 React Material-UI 的教程,特别是与简单的 Select 下拉菜单有关。

They are using the following json dataset object snippet for their code that looks like this:他们正在使用以下 json 数据集 object 片段来编写如下所示的代码:

{
  "AF": "Afghanistan",
  "AL": "Albania",
  "DZ": "Algeria",
  "AS": "American Samoa",
  "AD": "Andorra",
  "AO": "Angola",
  "AI": "Anguilla"
}

and the React code they use to build the select is as follows, where options here is the above json dataset:他们用来构建 select 的 React 代码如下,这里的选项是上面的 json 数据集:

  return (
    <TextField>
      {Object.keys(options).map((item, pos) => {
        return (
          <MenuItem key={pos} value={item}>
            {options[item]}
          </MenuItem>
        )
      })}
    </TextField>
  );

Now I am trying to build something similar to the above but my dataset is actually an array of objects, ie:现在我正在尝试构建与上述类似的东西,但我的数据集实际上是一个对象数组,即:

[
    {
        "job_id": 1,
        "job_name": "Engineer"
    },
    {
        "job_id": 2,
        "job_name": "Scientist"
    },
    {
        "job_id": 3,
        "job_name": "Teacher"
    }
]

My question is, how can I achieve the above React code to construct my React Material UI Select but instead of using an object, I would like to use my array of objects where the name shown in the select drop-down is job_name and the value return is job_id ?我的问题是,我怎样才能实现上述 React 代码来构造我的 React Material UI Select,而不是使用 object,我想使用我的对象数组,其中 Z99938282F0407185994-E18F 中显示的名称是 jobname 和 6EF4994- job_name返回是job_id

I have tried the following, but nothing is returned:我尝试了以下方法,但没有返回任何内容:

{options.map(option => {
          return (
            <MenuItem key={option.value} value={option.value}>
              {option.key}
            </MenuItem>
          )
})}

Added: In addition to the above, what is the best way of checking between the first dataset (object) and my data set - array of objects and then using this check to distinguish between the two methods of displaying the data within the correct Material-UI Select code?补充:除上述之外,在第一个数据集(对象)和我的数据集 - 对象数组之间进行检查的最佳方法是什么,然后使用此检查来区分在正确的 Material-UI Select 内显示数据的两种方法代码?

You need to access the item options differently since key and value are not set in the objects within the array.您需要以不同的方式访问项目选项,因为键和值未在数组中的对象中设置。 The possible options are job_id and job_name .可能的选项是job_idjob_name

So try this:所以试试这个:

{options.map(option => {
          return (
            <MenuItem key={option.job_id} value={option.job_id}>
              {option.job_name}
            </MenuItem>
          )
})}

Map will be called on every item so that option here is one of the elements in your array. Map 将在每个项目上调用,因此此处的选项是数组中的元素之一。

Update: to distinguish if the object is an array or not you could use Array.isArray :更新:要区分 object 是否为数组,您可以使用Array.isArray

{(Array.isArray(options) ? options.map(({job_id, job_name})=> ([job_id, job_name])) : Object.entries(options)).map(([key,value])=> {
          return (
            <MenuItem key={key} value={key}>
              {value}
            </MenuItem>
          )
})}

This would work but maybe should be done separately to keep the jsx lean and avoid overloading the render function.这会起作用,但可能应该单独完成以保持 jsx 精简并避免渲染 function 过载。

A Complete example with sample component and sample URLs带有示例组件和示例 URL 的完整示例

import { FormControl, InputLabel, MenuItem, Select, SelectChangeEvent } from '@mui/material';
import axios from 'axios';
import * as React from 'react';
import { useEffect, useState } from 'react';

type Props = {};

export const ProductsSearch = (props: Props) => {
    var token = localStorage.getItem('token');
    const requestHeader = {
        headers: {
            Authorization: `Bearer ${token}`
        }
    };

    const [brands, setBrands] = useState<any[]>([]);
    const [categories, setCategories] = useState<any[]>([]);
    const [searchedProducts, setSearchedProducts] = useState<any[]>([]);

    const [brand, setBrand] = useState('');
    const handleChangeBrand = (event: SelectChangeEvent) => {
        setBrand(event.target.value);
    };

    const [category, setCategory] = useState('');
    const handleChangeCategory = (event: SelectChangeEvent) => {
        setCategory(event.target.value);
    };

    useEffect(() => {
        let brandsUrl = `http://localhost:5000/api/products/brands/all`;
        let categoriesUrl = `http://localhost:5000/api/products/categories/all`;
        let searchedProductsUrl = `http://localhost:5000/api/products/byBrandAndcategory/1/5`;

        axios.all([axios.get(brandsUrl, requestHeader), axios.get(categoriesUrl, requestHeader), axios.get(searchedProductsUrl, requestHeader)]).then(axios.spread((...responses) => {
            setBrands(responses[0].data);
            setCategories(responses[1].data);
            setSearchedProducts(responses[2].data);
        })).catch(errors => {
            console.log('Error fetching multiple requests');
        });
    }, []);

    return (
        <>
            <FormControl variant="filled" sx={{ m: 1, minWidth: 200 }}>
                <InputLabel id="brand-select-label">Brand</InputLabel>
                <Select
                    labelId="brand-select-label"
                    id="brand-select"
                    value={brand}
                    onChange={handleChangeBrand}
                >
                    {
                        brands.map((brand) => {
                            return <MenuItem value={brand.brand_id} key={brand.brand_id}>{brand.brand_name}</MenuItem>
                        })
                    }
                </Select>
            </FormControl>

            <FormControl variant="filled" sx={{ m: 1, minWidth: 200 }}>
                <InputLabel id="category-select-label">Category</InputLabel>
                <Select
                    labelId="category-select-label"
                    id="category-select"
                    value={category}
                    onChange={handleChangeCategory}
                >
                    {
                        categories.map((category) => {
                            return <MenuItem key={category.category_id} value={category.category_id}>{category.category_name}</MenuItem>
                        })
                    }
                </Select>
            </FormControl>

            {brands.length} | {categories.length} | {searchedProducts.length}
        </>
    );
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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