问题描述
我正在创建以下组件:
它将包含一个对象数组,其中每个对象都是一个处方,其中包含来自选择的药物名称和用于 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: '',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}
/>