简体   繁体   English

Material-UI TextField 失去对每个 onChange 的关注

[英]Material-UI TextField loses focus on every onChange

I am creating the following component:我正在创建以下组件:

添加药物的组件

It will contain an array of objects, where each object is a prescription, with the medicine name from the select and a TextField for the Dosis.它将包含一个对象数组,其中每个 object 是一个处方,药物名称来自 select 和一个用于 Dosis 的 TextField。

My problem is that the TextField loses focus on every onChange() and is very frustrating because it cannot be edited on a single focus.我的问题是 TextField 失去了对每个 onChange() 的关注,并且非常令人沮丧,因为它不能在单个焦点上进行编辑。

This is my component:这是我的组件:

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>
    )
}

And here is where I set the component:这是我设置组件的地方:

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

Adding and removing objects from the array works perfect.从数组中添加和删除对象非常完美。 selecting the medicine from the select, also works perfect.从 select 中选择药物,效果也很好。 the only problem I have is when editing the Dosis TextField, with every character, the focus is lost and I have to click again on the TextField.我唯一的问题是在编辑 Dosis TextField 时,每个字符都会失去焦点,我必须再次单击 TextField。

Please help me getting this fixed!!!请帮我解决这个问题!!!

After searching a lot, finally I found the solution.经过大量搜索,我终于找到了解决方案。 Actually when using nanoid() to create unique keys, on every state update React re-renders all components and since the id of both the List and the TextField component are regenerated by nanoid on every render, React loses track of the original values, that is why Focus was lost.实际上,当使用 nanoid() 创建唯一键时,在每次 state 更新时,React 都会重新渲染所有组件,并且由于 List 和 TextField 组件的 ID 在每次渲染时都由 nanoid 重新生成,因此 React 会丢失原始值的跟踪,即这就是焦点丢失的原因。

What I did was keeping the keys uncuttable:我所做的是保持键不可切割:

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

and

<TextField
    key={`dosis-${index}`}
    fullWidth
    // id={`${index}-dosis-${medication}`}
    label='Dosis'
    name='dosis'
    onChange={(event) =>
        handleChange(index, event.target)
    }
    value={medication.dosis}
/>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM