Множественный выбор с опциями в виде массива объектов

#javascript #reactjs #material-ui

Вопрос:

У меня есть следующий компонент для выбора ролей:

введите описание изображения здесь

 export const MultipleSelectChip = ({
  options,
  label,
  error,
  onRolesUpdate,
}: Props) => {
  const theme = useTheme();
  const [selectedOptions, setSelectedOptions] = React.useState<string[]>([]);

  const handleChipChange = (
    event: SelectChangeEvent<typeof selectedOptions>,
  ) => {
    const {
      target: { value },
    } = event;
    setSelectedOptions(
      // On autofill we get a the stringified value.
      typeof value === 'string' ? value.split(',') : value,
    );
  };

  return (
    <div>
      <FormControl sx={{ m: 1, width: 300 }}>
        <InputLabel id="multiple-chip-label">{label}</InputLabel>
        <Select
          required
          labelId="multiple-chip-label"
          error={error}
          id="demo-multiple-chip"
          multiple
          value={selectedOptions}
          onChange={handleChipChange}
          input={<OutlinedInput id="select-multiple-chip" label={label} />}
          renderValue={(selected) => (
            <Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 0.5 }}>
              {selected.map((value) => (
                <Chip key={value} label={value} />
              ))}
            </Box>
          )}
          MenuProps={MenuProps}
        >
          {options.map((propOption) => (
            <MenuItem
              key={propOption.id}
              value={propOption.name}
              style={getStyles(propOption, selectedOptions, theme)}
            >
              {propOption.name}
            </MenuItem>
          ))}
        </Select>
        <FormHelperText>Here's my helper text</FormHelperText>
      </FormControl>
    </div>
  );
};
 

Для опций у меня есть массив объектов с идентификатором и именем, дело в том, что я хочу использовать имена для отображения чипов и идентификаторы, чтобы передать их родительскому компоненту для запроса на добавление. Я тоже не знаю, как получить удостоверения личности.

Вот пример: https://codesandbox.io/s/6ry5y?file=/demo.tsx но использует массив строк вместо массива объектов.

Вот как выглядят «варианты»:

 const rolesDummy: Role[] = [
    { id: '61fb0f25-34aa-46c6-8683-093254223dcd', name: 'HR' },
    { id: '949b9b1e-d3f8-45cb-a061-08da483bd486', name: 'Interviewer' },
    { id: 'c09ae2d4-1335-4ef0-8d4b-ee9529796b52', name: 'Hiring Manager' },
  ];
 

И мне нужно вернуть только выбранные идентификаторы

Спасибо!

Ответ №1:

Если вы передадите параметр в качестве объекта, вы можете отобразить каждый MenuItem из option.id них как a key и option.name как метку. Он MenuItem идентифицируется по идентификатору:

 <Select {...}>
  {options.map((option) => (
    <MenuItem key={option.id} value={option.id}>
      {option.name}
    </MenuItem>
  ))}
</Select>
 

Для отображения имени в выбранном Chip . Используйте renderValue , но он предоставляет вам только выбранные значения (массив option.id ), поэтому вам нужно найти опцию, чтобы получить имя:

 renderValue={(selected) => {
  return (
    <Box>
      {selected.map((value) => {
        const option = options.find((o) => o.id === value);
        return <Chip key={value} label={option.name} />;
      })}
    </Box>
  );
}}
 

Теперь вы можете получить массив выбранных идентификаторов, добавив change обработчик:

 onChange={e => console.log(e.target.value)}
 

Демо-версия Codesandbox