【问题标题】:React Creating Dynamic Select and Option Elements with Material-UIReact 使用 Material-UI 创建动态选择和选项元素
【发布时间】:2021-05-01 18:06:33
【问题描述】:

所以,老实说,我认为这需要 15 分钟,但我现在大约需要 5 个小时。让我非常困扰的是,我知道这是一个简单的解决方案,而且我也尝试了几种不同的方法。

我有一个 React 应用程序,在诊断组件中,我有两个下拉元素,允许用户选择他们设备的品牌和型号。 What I'm trying to do is allow the user to choose which Make they have, and when the make dropdown is selected, the models dropdown populates automatically.

这是我的 MakeandModel.js 文件:

import React, { useState, useEffect } from 'react';
import { makeStyles } from '@material-ui/core/styles';
import FormControl from '@material-ui/core/FormControl';
import InputLabel from '@material-ui/core/InputLabel';
import Select from '@material-ui/core/Select';
import MenuItem from '@material-ui/core/MenuItem';

import makeandmodel_DATA from './makeandmodel_DATA';

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

console.log(makeandmodel_DATA);

export default () => {
    const classes = useStyles();
    const [data, setData] = useState();
    const [make, setMake] = useState('');
    const [model, setModel] = useState('');

    useEffect(() => {
        
    });

    const handleMakeChange = (event) => (
        setMake(event.target.value)
    );

    const handleModelChange = (event) => (
        setModel(event.target.value)
    );

    return (
        <>
            <FormControl variant="outlined" className={classes.formControl}>
                <InputLabel id="demo-simple-select-outlined-label">Make</InputLabel>
                <Select
                    labelId="demo-simple-select-outlined-label"
                    id="demo-simple-select-outlined"
                    value={make}
                    onChange={handleMakeChange}
                    label="Make"
                >
                    <MenuItem value="">
                        <em>Choose a Make</em>
                    </MenuItem>
                    {makeandmodel_DATA.map((make, index) => (
                        <MenuItem key={index} value={make.name}>{make.name}</MenuItem>
                    ))}
                </Select>
            </FormControl>

            <FormControl variant="outlined" className={classes.formControl}>
                <InputLabel id="demo-simple-select-outlined-label">Model</InputLabel>
                <Select
                    labelId="demo-simple-select-outlined-label"
                    id="demo-simple-select-outlined"
                    value={model}
                    onChange={handleModelChange}
                    label="Model"
                >
                    <MenuItem value="">
                        <em>Choose a Model</em>
                    </MenuItem>
                    
                </Select>
            </FormControl>
            <br />
       </>
    );
};

我还导入了一些示例数据,以尝试填充我的品牌和型号下拉列表。以下是 makeandmodel_DATA.json 文件中的代码:

[
    {
        "name": "Dyson",
        "models": [
            {
                "name": "v12"
            },
            {
                "name": "v10"
            },
            {
                "name": "ball"
            }
        ]
    },
    {
        "name": "Oreck",
        "models": [
            {
                "name": "Upright"
            },
            {
                "name": "Unique"
            },
            {
                "name": "XL"
            }
        ]
    },
    {
        "name": "Electrolux",
        "models": [
            {
                "name": "Classic"
            },
            {
                "name": "Vintage"
            },
            {
                "name": "New School"
            }
        ]
    },
    {
        "name": "Kirby",
        "models": [
            {
                "name": "Heavy"
            },
            {
                "name": "Light"
            },
            {
                "name": "Regular"
            }
        ]
    },
    {
        "name": "Hoover",
        "models": [
            {
                "name": "Windtunnel"
            },
            {
                "name": "Back"
            },
            {
                "name": "Upright"
            }
        ]
    }
]

我尝试映射导入的数据,但每次我这样做以查找模型时,我最终都会返回 undefined。

我也尝试过连接 useEffect 函数,但也无法准确地确定以这种方式正确连接它。

就像我说的,我觉得解决方案非常简单,但我忽略了一些基本的东西。我真的只是在寻找一个看起来很干净而且效果很好的超级简单的解决方案。如果您需要任何其他信息来帮助我们解决此问题,请尽管询问。

提前致谢!

【问题讨论】:

    标签: javascript reactjs react-hooks material-ui dropdown


    【解决方案1】:

    这里的最佳做法是创建一个对象,您可以在其中使用 Make 名称保存模型。

    const models = React.useMemo(() => {
      const modelsValues = {};
      makeandmodel_DATA.forEach(({ name, models }) => {
        modelsValues[name] = models;
      })
    
     return modelsValues;
    })
    

    您只需要在执行此操作时保存模型名称。 然后您需要访问选定的Make 模型,最后您的Make 选择将是这样的:

             {make && <FormControl variant="outlined" className={classes.formControl}>
                <InputLabel id="demo-simple-select-outlined-label">Model</InputLabel>
                <Select
                    labelId="demo-simple-select-outlined-label"
                    id="demo-simple-select-outlined"
                    value={model}
                    onChange={handleModelChange}
                    label="Model"
                >
                    <MenuItem value="">
                        <em>Choose a Model</em>
                    </MenuItem>
                  {models[make] ? models[make].map(model=> {
                    // Here goes your models option
                    return <MenuItem value="">
                        <em>Choose a Model</em>
                    </MenuItem>
                    }) : null
                   }
                </Select>
            </FormControl>}
    

    也许我有一个错字,但如果你能给我一个沙盒,这可以更简单地修复。

    【讨论】:

      【解决方案2】:

      这是一个很好的解决方案!

      我做了同样的事情,我在 map 函数中添加了一个索引,为每个 MenuItem 添加一个键,并将每个 MenuItem 上的 value 属性和子项设置为 model.name

      {make && <FormControl variant="outlined" className={classes.formControl}>
               <InputLabel id="demo-simple-select-outlined-label">Model</InputLabel>
               <Select
                   labelId="demo-simple-select-outlined-label"
                   id="demo-simple-select-outlined"
                   value={model}
                   onChange={handleModelChange}
                   label="Model"
               >
                   <MenuItem value="">
                       <em>Choose a Model</em>
                   </MenuItem>
                   {models[make] 
                       ? models[make].map((model, index) => (
                           <MenuItem key={index} value={model.name}>{model.name}</MenuItem>
                       ))
                       : null
                   }
          
      
           </Select>
      </FormControl>}
      

      【讨论】:

      • 很好,我只是忘了在选项中添加值和键?
      猜你喜欢
      • 2020-11-26
      • 1970-01-01
      • 2016-04-02
      • 1970-01-01
      • 1970-01-01
      • 2018-01-11
      • 2015-03-04
      • 1970-01-01
      • 2018-01-30
      相关资源
      最近更新 更多