javascript - Material-UI TextField 失去了对每个 onChange 的关注
问题描述
我正在创建以下组件:
它将包含一个对象数组,其中每个对象都是一个处方,带有来自选择的药物名称和一个用于 Dosis 的 TextField。
我的问题是 TextField 失去了对每个 onChange() 的关注并且非常令人沮丧,因为它不能在单个焦点上进行编辑。
这是我的组件:
const MedicineSelect = ({ medications, setMedications, ...props }) => {
const { medicines } = useMedicines()
const classes = useStyles()
const handleChange = (index, target) => {
// setAge(event.target.value)
const newMedications = cloneDeep(medications)
newMedications[index][target.name] = target.value
setMedications(newMedications)
}
const handleAddMedicine = () => {
const newMedications = cloneDeep(medications)
newMedications.push({ medicine: '', dosis: '', time: '' })
setMedications(newMedications)
}
const handleDeleteMedicine = (index) => {
console.log('DELETE: ', index)
const newMedications = cloneDeep(medications)
newMedications.splice(index, 1)
setMedications(newMedications)
}
return (
<Paper style={{ padding: 5 }}>
<List>
{medications.map((medication, index) => (
<ListItem key={nanoid()} divider alignItems='center'>
<ListItemIcon>
<Tooltip title='Eliminar'>
<IconButton
className={classes.iconButton}
onClick={() => handleDeleteMedicine(index)}
>
<HighlightOffOutlinedIcon />
</IconButton>
</Tooltip>
</ListItemIcon>
<FormControl className={classes.formControl}>
<InputLabel
id={`${index}-select-${medication}-label`}
>
Medicamento
</InputLabel>
<Select
labelId={`${index}-select-${medication}-label`}
id={`${index}-select-${medication}`}
name='medicine'
value={medication.medicine}
onChange={(event) =>
handleChange(index, event.target)
}
>
{medicines.map((medicine) => (
<MenuItem
key={nanoid()}
value={medicine.name}
>
{medicine.name}
</MenuItem>
))}
</Select>
</FormControl>
<TextField
// fullWidth
id={`${index}-text-${medication}`}
label='Dosis'
name='dosis'
onChange={(event) =>
handleChange(index, event.target)
}
value={medication.dosis}
/>
</ListItem>
))}
<Button onClick={handleAddMedicine}>+ agregar</Button>
</List>
</Paper>
)
}
这是我设置组件的地方:
const [medications, setMedications] = useState([
{ medicine: '', dosis: '', time: '' },
])
...
<Grid item md={12} xs={12}>
<Accordion>
<AccordionSummary
expandIcon={<ExpandMoreIcon />}
aria-controls='panel1a-content'
id='panel1a-header'
>
<Typography variant='h4'>
Tratamiento:
</Typography>
</AccordionSummary>
<AccordionDetails>
<Container disableGutters>
<MedicineSelect
medications={medications}
setMedications={setMedications}
/>
</Container>
</AccordionDetails>
</Accordion>
</Grid>
...
从数组中添加和删除对象非常完美。从选择中选择药物,也很完美。我唯一的问题是在编辑 Dosis TextField 时,每个字符都会失去焦点,我必须再次单击 TextField。
请帮我解决这个问题!!!
解决方案
经过大量搜索,我终于找到了解决方案。实际上,当使用 nanoid() 创建唯一键时,在每次状态更新时,React 都会重新渲染所有组件,并且由于 List 和 TextField 组件的 id 在每次渲染时都由 nanoid 重新生成,因此 React 会丢失原始值,即这就是焦点丢失的原因。
我所做的是保持键不可切割:
<ListItem key={`medication-${index}`} divider alignItems='center'>
和
<TextField
key={`dosis-${index}`}
fullWidth
// id={`${index}-dosis-${medication}`}
label='Dosis'
name='dosis'
onChange={(event) =>
handleChange(index, event.target)
}
value={medication.dosis}
/>
推荐阅读
- javascript - 如何使用 React 中的受控组件删除 :checked 伪类?
- python - 模态视图中的计算繁重方法
- powerbi - 计算层次结构中总计的百分比
- c# - 如何在 .Net Core 2.2 中正确使用 ConfigurationManager.GetSection()
- google-maps - 我如何从谷歌地图的地方 api 对象中获取纬度和经度?
- python - Cython 的 language_level 3 和 3str 有什么区别?
- python - MultiIndex DataFrame:如何根据其他列中的值创建新列?
- bash - 意外令牌完成 bash 脚本附近的语法错误
- rest - 无法使用 invoke-webrequest/restmethod 从共享点检索正确的错误
- java - 使用带有多个 ClassLoader 的 Hibernate/JPA 访问多个数据库