'How to get the index of the selected item from a dropdown in ReactJs and material UI?

This is the component for Dropdown:

<DropDownField
  name={formElement.name}
  label={formElement.name}
  value={formik.values[formElement.name] || ''}                     
  dropDownItems={formElement.name === 'Loan Details' ? loanEnum : formElement.enum}
  className={classes.flexGrow}
  onChange={dropDownChangeHandler}
  error={formik.touched[formElement.name] && Boolean(formik.errors[formElement.name])}
  helperText={formik.touched[formElement.name] && formik.errors[formElement.name]}
 />

and the DropDownField component:

<FormControl fullWidth>
        {/* eslint-disable-next-line */}
        <InputLabel id="simple-select-label">{props.label}</InputLabel>
        <Select labelId="simple-select-label" id="simple-select" {...props}>
            {/* eslint-disable-next-line */}
            {props.dropDownItems.map((element, index) => (
                <MenuItem key={element + index} value={element}>
                    {element}
                </MenuItem>
            ))}
        </Select>
</FormControl>

onChange function:

const dropDownChangeHandler = async (e) => {
        const loanDetails = await LoanDetailsService.search(formik.values['Employee Number']);
        formik.handleChange(e);
        console.log(loanDetails);
        formik.setFieldValue('Loan Type', loanDetails[index]['Loan Type']);
    };

Now in the onChange function how do i get the index of the dropdown items?



Solution 1:[1]

I think you could try adding a data attribute to your menu items, e.g.:

{props.dropDownItems.map((element, index) => (
    <MenuItem key={element + index} value={element} data-index={index}>
        {element}
    </MenuItem>
))}

And then getting that index from e.currentTarget.dataset.index or by grabbing the second argument (child) sent to the event handler as detailed in the onChange section on this page.

e.g. something like:

const dropDownChangeHandler = async (e) => {
    const index = +e.currentTarget.dataset.index;
    const loanDetails = await LoanDetailsService.search(formik.values['Employee Number']);
    formik.handleChange(e);
    console.log(loanDetails);
    formik.setFieldValue('Loan Type', loanDetails[index]['Loan Type']);
};

or

const dropDownChangeHandler = async (e, child) => {
    const index = child.props['data-index'];
    const loanDetails = await LoanDetailsService.search(formik.values['Employee Number']);
    formik.handleChange(e);
    console.log(loanDetails);
    formik.setFieldValue('Loan Type', loanDetails[index]['Loan Type']);
};

Solution 2:[2]

You are mapping over the elements, the map method gives you the indices of the element, you could bubble the index of the given selected element via handler using the onClick prop

{props.dropDownItems.map((element, index) => (
<MenuItem key={element + index} value={element} onClick={()=> handleItemClick(index)} > 
{element}
</MenuItem> 
))}

The handleItemClick code will be as in the following

const handleItemClick = (idx) => {
console.log(idx); 
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Ben Stephens
Solution 2 Amr