Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
104 views
in Technique[技术] by (71.8m points)

javascript - React Creating Dynamic Select and Option Elements with Material-UI

So, I honestly thought this would take me 15 minutes, but I'm up around 5 hours right now. What's bothering me so much is that I know it's a simple solution, and I've tried a few different approaches as well.

I have a React App, and inside the Diagnosis Component, I have two dropdown elements that allow users to choose the Make and Model of their appliance. 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.

Here is my MakeandModel.js file:

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 />
       </>
    );
};

I also have some sample data I'm importing to try to populate my Make and Model dropdowns. Here is the code from the makeandmodel_DATA.json file:

[
    {
        "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"
            }
        ]
    }
]

I've tried to map over the imported data, but every time I do that to find the models, I end up returning undefined.

I've also tried to wire up the useEffect function, but couldn't figure out exactly to wire it up correctly that way either.

Like I said, I feel like the solution is super simple, but I'm overlooking something fundamental. I'm really just looking for a super simple solution that looks clean and works well. If you need any other information to help us solve this problem, just ask.

Thanks in advance!

question from:https://stackoverflow.com/questions/65927056/react-creating-dynamic-select-and-option-elements-with-material-ui

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The best practice here is to create an object where you save your models by the Make name.

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

 return modelsValues;
})

You only need to save the model name as you are doing it. Then you need to access to the selected Make models, and finally your Make select is gonna be something like this:

         {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>}

Maybe I have a typo but If you could give me a sandbox this can be more simple to fix.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...