React Material-UI Select 使用对象数组作为源
React Material-UI Select using an array of objects as the source
希望能得到一些帮助。我目前正在学习使用 React Material-UI 的教程,专门用于处理简单的 Select 下拉菜单。
他们的代码使用以下 json 数据集对象片段,如下所示:
{
"AF": "Afghanistan",
"AL": "Albania",
"DZ": "Algeria",
"AS": "American Samoa",
"AD": "Andorra",
"AO": "Angola",
"AI": "Anguilla"
}
他们用来构建 select 的 React 代码如下,这里的选项是上面的 json 数据集:
return (
<TextField>
{Object.keys(options).map((item, pos) => {
return (
<MenuItem key={pos} value={item}>
{options[item]}
</MenuItem>
)
})}
</TextField>
);
现在我正在尝试构建与上面类似的东西,但我的数据集实际上是一个对象数组,即:
[
{
"job_id": 1,
"job_name": "Engineer"
},
{
"job_id": 2,
"job_name": "Scientist"
},
{
"job_id": 3,
"job_name": "Teacher"
}
]
我的问题是,我怎样才能实现上面的 React 代码来构造我的 React Material UI Select 但是我不想使用对象,而是想使用我的数组select 下拉列表中显示的名称为 job_name
且值 return 为 job_id
?
的对象的数量
我尝试了以下方法,但没有任何结果 returned:
{options.map(option => {
return (
<MenuItem key={option.value} value={option.value}>
{option.key}
</MenuItem>
)
})}
添加: 除了上述之外,检查第一个数据集(对象)和我的数据集 - 对象数组然后使用此检查的最佳方法是什么区分在正确的 Material-UI Select 代码中显示数据的两种方法?
您需要以不同方式访问项目选项,因为键和值未在数组中的对象中设置。可能的选项是 job_id
和 job_name
.
所以试试这个:
{options.map(option => {
return (
<MenuItem key={option.job_id} value={option.job_id}>
{option.job_name}
</MenuItem>
)
})}
Map 将在每个项目上调用,因此此处的选项是您的数组中的元素之一。
更新:区分对象是否为数组可以使用 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>
)
})}
这可行,但也许应该单独完成以保持 jsx 精简并避免渲染函数过载。
带有示例组件和示例 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}
</>
);
};
希望能得到一些帮助。我目前正在学习使用 React Material-UI 的教程,专门用于处理简单的 Select 下拉菜单。
他们的代码使用以下 json 数据集对象片段,如下所示:
{
"AF": "Afghanistan",
"AL": "Albania",
"DZ": "Algeria",
"AS": "American Samoa",
"AD": "Andorra",
"AO": "Angola",
"AI": "Anguilla"
}
他们用来构建 select 的 React 代码如下,这里的选项是上面的 json 数据集:
return (
<TextField>
{Object.keys(options).map((item, pos) => {
return (
<MenuItem key={pos} value={item}>
{options[item]}
</MenuItem>
)
})}
</TextField>
);
现在我正在尝试构建与上面类似的东西,但我的数据集实际上是一个对象数组,即:
[
{
"job_id": 1,
"job_name": "Engineer"
},
{
"job_id": 2,
"job_name": "Scientist"
},
{
"job_id": 3,
"job_name": "Teacher"
}
]
我的问题是,我怎样才能实现上面的 React 代码来构造我的 React Material UI Select 但是我不想使用对象,而是想使用我的数组select 下拉列表中显示的名称为 job_name
且值 return 为 job_id
?
我尝试了以下方法,但没有任何结果 returned:
{options.map(option => {
return (
<MenuItem key={option.value} value={option.value}>
{option.key}
</MenuItem>
)
})}
添加: 除了上述之外,检查第一个数据集(对象)和我的数据集 - 对象数组然后使用此检查的最佳方法是什么区分在正确的 Material-UI Select 代码中显示数据的两种方法?
您需要以不同方式访问项目选项,因为键和值未在数组中的对象中设置。可能的选项是 job_id
和 job_name
.
所以试试这个:
{options.map(option => {
return (
<MenuItem key={option.job_id} value={option.job_id}>
{option.job_name}
</MenuItem>
)
})}
Map 将在每个项目上调用,因此此处的选项是您的数组中的元素之一。
更新:区分对象是否为数组可以使用 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>
)
})}
这可行,但也许应该单独完成以保持 jsx 精简并避免渲染函数过载。
带有示例组件和示例 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}
</>
);
};