Javascript 材质UI文本字段在每次更改时都失去焦点

Javascript 材质UI文本字段在每次更改时都失去焦点,javascript,reactjs,material-ui,textfield,Javascript,Reactjs,Material Ui,Textfield,我正在创建以下组件: const [medications, setMedications] = useState([ { medicine: '', dosis: '', time: '' }, ]) ... <Grid item md={12} xs={12}> <Accordion> <Accordio

我正在创建以下组件:

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>
...

它将包含一个对象数组,其中每个对象都是一个处方,具有来自select的药物名称和剂量的文本字段

我的问题是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 MedicineSelect=({medicines,setmedicines,…props})=>{
const{medicines}=useMedicines()
常量类=useStyles()
常量handleChange=(索引,目标)=>{
//设置(event.target.value)
const newmedicines=cloneDeep(药物)
新药物[index][target.name]=target.value
药物(新药)
}
const handleAddMedicine=()=>{
const newmedicines=cloneDeep(药物)
新药。推送({药物:'',剂量:'',时间:'})
药物(新药)
}
const handleDeleteMedicine=(索引)=>{
console.log('DELETE:',index)
const newmedicines=cloneDeep(药物)
新药.拼接(索引,1)
药物(新药)
}
返回(
{medicines.map((药物,索引)=>(
handleDeleteMedicine(索引)}
>
药物
handleChange(索引、事件、目标)
}
>
{medicines.map((medicine)=>(
{medicine.name}
))}
handleChange(索引、事件、目标)
}
值={medicing.dosis}
/>
))}
+阿格雷戈
)
}
下面是我设置组件的地方:

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>
...
const[medicines,setmedicines]=useState([
{药物:'',剂量:'',时间:'},
])
...
塔塔曼托:
...
从数组中添加和删除对象效果非常好。从“选择”菜单中选择药物,效果也很完美。我唯一的问题是编辑Dosis文本字段时,每个字符的焦点都会丢失,我必须再次单击文本字段


请帮我把这个修好

经过多次搜索,我终于找到了解决方案。实际上,当使用nanoid()创建唯一键时,在每次状态更新时,React会重新渲染所有组件,并且由于列表和文本字段组件的id在每次渲染时都由nanoid重新生成,React会丢失原始值的轨迹,这就是为什么会丢失焦点

我所做的是保持钥匙不可切割:

<ListItem key={`medication-${index}`} divider alignItems='center'>


handleChange(索引、事件、目标)
}
值={medicing.dosis}
/>

什么是
nanoid
你有没有可能在沙盒中复制它?@codemonkey,当然,我在这个链接上创建了一个沙盒,提前感谢你的时间@Jayce444,nanoid是javascript库,用于为元素创建随机和唯一的“键”。i、 当你有一个朋友的时候。数组中的元素,而不是执行key=index,而是执行key=nanoid(),因为索引只是一个数字,如果您对代码不太在意,它可以重复。