Я использую MUI Select для опции множественного выбора и показываю окончательные значения после некоторой модификации в виде чипов MUI. Теперь, когда я нажимаю «Добавить», чип не отображается в этот момент, однако, если я изменяю какое-либо значение имени и суффикса, страница отображается, а затем отображается чип. Может быть, я что-то упускаю. Любая помощь приветствуется.
import { useState, } from 'react';
import styled from 'styled-components';
import {OutlinedInput, MenuItem, Chip, useTheme, Select} from '@mui/material';
const ITEM_HEIGHT = 48;
const ITEM_PADDING_TOP = 8;
const MenuProps = {
PaperProps: {
style: {
maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP,
width: 250,
},
},
};
const EditUser =styled.div`
display: flex;
align-items: center;
justify-content: flex-start;
margin-left:5px;
margin-top: 10px;
margin-bottom: 20px;
`
const Label = styled.label`
width: 100px;
margin: 10px;
`
const LabelInputWrapper = styled.div`
margin-bottom:25px;
flex:1 0 30%;
display: ${(props) => props.disp};
`
const Adduserformcont = styled.div`
display: flex;
flex-wrap:wrap;
margin:10px;
`
const AddChrgWrapper = styled.div`
display: flex;
`
const names = [
'Oliver Hansen',
'Van Henry',
'April Tucker',
'Ralph Hubbard',
'Omar Alexander',
'Carlos Abbott',
'Miriam Wagner',
'Bradley Wilkerson',
'Virginia Andrews',
'Kelly Snyder',
];
function getStyles(name, personName, theme) {
return {
fontWeight:
personName.indexOf(name) === -1
? theme.typography.fontWeightRegular
: theme.typography.fontWeightMedium,
};
}
const desigSuffix = ["I","II", "III", "IV"];
const EditUsers = () => {
const theme = useTheme();
const [personName, setPersonName] = useState([]);
const [value, setValue] = useState({})
const [finalValue, setFinalValue] =useState([])
const onChangeUserForm = (event) => {
if (event.target.name === 'selectMultiAddnCharg'){
setPersonName(event.target.value)
}
let temp = {...value, [event.target.name]:event.target.value}
setValue(temp);
console.info(temp)
}
const addWithSuffix = () => {
let tempArray = finalValue;
tempArray.push(`${value.adnCharge} (${value.desgnSuffix})`)
setFinalValue(tempArray)
}
return (
<>
<form>
<AddChrgWrapper>
<Label>Select name</Label>
<Select
name='selectMultiAddnCharg'
multiple
displayEmpty
value = {personName}
onChange = {onChangeUserForm}
input = {<OutlinedInput />}
renderValue = {(selected) => {
if (selected.length === 0) {
return <em>Select name</em>;
}
return selected.join(', ');
}}
MenuProps = {MenuProps}
inputProps = {{ 'aria-label': 'Without label' }}
>
<MenuItem disabled value = "">
<em>Placeholder</em>
</MenuItem>
{names.map((name) => (
<MenuItem
key = {name}
value = {name}
style = {getStyles(name, personName, theme)}
>
{name}
</MenuItem>
))}
</Select>
</AddChrgWrapper>
<LabelInputWrapper name = "adnCharge">
<Label>Name</Label>
<select name = "adnCharge" onChange = {onChangeUserForm}>
<option>Select</option>
{personName.map((item,index) => <option key = {index}>{item}</option>)}
</select>
</LabelInputWrapper>
<LabelInputWrapper name = "desgnSuffix" >
<Label>Suffix</Label>
<select name = "desgnSuffix" onChange = {onChangeUserForm}>
<option>Select</option>
{desigSuffix.map((item,index) => <option key = {index}>{item}</option>)}
</select>
</LabelInputWrapper>
<button type = "button" onClick = {(e)=>addWithSuffix(e)}>Add</button>
<div>{finalValue.map((item, index)=><Chip key = {index} label = {item}/>)}</div>
</form>
</>
)
}
export default EditUsers
Я хочу просмотреть фишки, когда я нажимаю кнопку «Добавить».
Я могу просматривать чипы с вашим кодом без каких-либо изменений, если я изменю кнопку выбора «Имя» или «Суффикс». Если я только изменю multi-select , я все еще смогу просматривать чипы, но со значениями как «неопределенные». Это потому, что вы отображаете значения adnCharge и desgnSuffix в чипах, а не значение selectMultiAddnCharg.
После выбора одного имени и одного суффикса, а затем нажатия кнопки «Добавить» в первый раз, я должен иметь возможность просматривать чипы, но я их не вижу.





В функции addWithSuffix, когда вы объявляете tempArray, это не новый массив, но вы все равно напрямую изменяете состояние finalValue, а это не разрешено.
Из документов React:
state — это ссылка на состояние компонента во время применения изменения. Он не должен быть напрямую мутирован. Вместо этого изменения должны быть представлены путем создания нового объекта на основе входных данных из состояния.
Вы можете объявить новую переменную массива на основе старого состоянияlet tempArray = [...finalValue]
или используйте первый аргумент setFinalValue, который является старым состоянием
const addWithSuffix = () => {
let tempArray = [...finalValue];
tempArray.push(`${value.adnCharge} (${value.desgnSuffix})`)
setFinalValue(tempArray)
}
ИЛИ
const addWithSuffix = () => {
setFinalValue(state => state.concat(`${value.adnCharge} (${value.desgnSuffix})`))
}
Демо:
const names = [
'Oliver Hansen',
'Van Henry',
'April Tucker',
'Ralph Hubbard',
'Omar Alexander',
'Carlos Abbott',
'Miriam Wagner',
'Bradley Wilkerson',
'Virginia Andrews',
'Kelly Snyder',
];
function getStyles(name, personName, theme) {
return {
fontWeight:
personName.indexOf(name) === -1
? theme.typography.fontWeightRegular
: theme.typography.fontWeightMedium,
};
}
const desigSuffix = ["I","II", "III", "IV"];
const EditUsers = () => {
const { useState } = React
const { OutlinedInput, MenuItem, Chip, useTheme, Select } = MaterialUI;
const theme = useTheme();
const [personName, setPersonName] = useState([]);
const [value, setValue] = useState({})
const [finalValue, setFinalValue] =useState([])
const onChangeUserForm = (event) => {
if (event.target.name === 'selectMultiAddnCharg'){
setPersonName(event.target.value)
}
let temp = {...value, [event.target.name]:event.target.value}
setValue(temp);
console.info(temp)
}
const addWithSuffix = () => {
// let tempArray = finalValue;
const newVal = `${value.adnCharge} (${value.desgnSuffix})`
// tempArray.push(newVal)
setFinalValue(state => state.concat(newVal))
}
return (
<>
<form>
<div>
<label>Select name</label>
<Select
name='selectMultiAddnCharg'
multiple
displayEmpty
value = {personName}
onChange = {onChangeUserForm}
input = {<OutlinedInput />}
renderValue = {(selected) => {
if (selected.length === 0) {
return <em>Select name</em>;
}
return selected.join(', ');
}}
inputProps = {{ 'aria-label': 'Without label' }}
>
<MenuItem disabled value = "">
<em>Placeholder</em>
</MenuItem>
{names.map((name) => (
<MenuItem
key = {name}
value = {name}
style = {getStyles(name, personName, theme)}
>
{name}
</MenuItem>
))}
</Select>
</div>
<div name = "adnCharge">
<label>Name</label>
<select name = "adnCharge" onChange = {onChangeUserForm}>
<option>Select</option>
{personName.map((item,index) => <option key = {index}>{item}</option>)}
</select>
</div>
<div name = "desgnSuffix" >
<label>Suffix</label>
<select name = "desgnSuffix" onChange = {onChangeUserForm}>
<option>Select</option>
{desigSuffix.map((item,index) => <option key = {index}>{item}</option>)}
</select>
</div>
<button type = "button" onClick = {(e)=>addWithSuffix(e)}>Add</button>
<div>{finalValue.map((item, index)=><Chip key = {index} label = {item}/>)}</div>
</form>
</>
)
}
const container = document.getElementById('root');
const root = ReactDOM.createRoot(container);
root.render(<EditUsers />);<!DOCTYPE html>
<html>
<head>
<script src = "https://unpkg.com/react@18/umd/react.production.min.js" crossorigin></script>
<script src = "https://unpkg.com/react-dom@18/umd/react-dom.production.min.js" crossorigin></script>
<script src = "https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script src = "https://unpkg.com/@mui/material@latest/umd/material-ui.production.min.js"></script>
</head>
<body>
<div id = "root"></div>
<script type = "text/babel" src = "./script.js"></script>
</body>
</html>Большое спасибо за помощь. Можете ли вы немного объяснить, почему это не сработало и как изменение помогло?
Я обновил свой ответ. Надеюсь объяснение понятно.
Что вам нужно на выходе? Вы хотите иметь возможность просматривать фишки, когда выбрана опция множественного выбора? Пожалуйста, уточните подробнее. будем рады помочь