Tengo las siguientes funciones que muestran un componente TextField o Select basado en un valor JSON que es Text o Select. Cuando trato de escribir en un campo de texto, solo puedo ingresar una letra antes de que se pierda el foco en el campo de texto. Luego puedo hacer clic en TextField nuevamente e ingresar otra letra antes de que se pierda el foco nuevamente. También hay un retraso notable entre la pulsación de una tecla y la aparición del símbolo correspondiente en el TextField.
El código completo se puede encontrar aquí
Este es mi código de cómo obtengo mi respuesta API, useEffect y mi función TextDetails que muestra los TextFields
const fetchDetails = async () => { setBusy(true); setDetails(await fetch(`/fiscalyears/FY2023/intakes/${params.id}/details`).then((response) => response.json())); setBusy(false); }; useEffect(() => { fetchDetails(); }, []); const TextDetails = ({ head, val, i }) => { return ( <TextField value={val || ""} onChange={(e) => { setDetails((prev) => { const update = [...prev.fields]; update[i] = { ...update[i], Value: e.target.value, }; return { ...prev, fields: update }; }); }} variant="outlined" margin="normal" label={head} /> ); }; const detailsComps = details["fields"]?.map((row, i) => { return row["FieldType"] === "Text" || row["FieldType"] === "Decimal" || row["FieldType"] === "Number" || row["FieldType"] === "Date" ? ( <TextDetails head={row?.FieldName} val={row?.Value} i={i} /> ) : ( <SelectDetails head={row.FieldName} val={row?.Value} choices={row?.Choices} i={i} /> ); }); ... return ( <Box> {detailsComps} </Box> )Lo siento, no puedo ver el código completo. Pero verifique si todo el Desde se vuelve a representar cada vez que ingresa un valor en el campo. La razón podría ser que con setDetails indicas a React que el valor de los detalles ha cambiado y debido a que detailsComps se procesa a partir de los detalles, es muy probable que se vuelva a procesar. Por lo tanto, se pierde el enfoque.
Solucioné este problema moviendo esta funcionalidad a la declaración de devolución de funciones:
... return ( <Box> {details["fields"]?.map((row, index) => { if (row?.FieldType === "Text" || row?.FieldType === "Decimal" || row?.FieldType === "Number") { return ( <TextField className="text-field" value={row?.Value || ""} onChange={(e) => { setDetails((prev) => { const update = [...prev.fields]; update[index] = { ...update[index], Value: e.target.value, }; return { ...prev, fields: update }; }); }} label={row["FieldName"]} /> ); } if (row?.FieldType === "Date") { return ( <TextField type="date" label={row["FieldName"]} InputLabelProps={{ shrink: true, }} /> ); } else { return ( <TextField value={row?.Value || ""} onChange={(e) => { setDetails((prev) => { const update = [...prev.fields]; update[index] = { ...update[index], Value: e.target.value, }; return { ...prev, fields: update }; }); }} select label={row?.FieldName} > {row?.Choices.map((choice) => ( <MenuItem key={choice} value={choice}> {choice} </MenuItem> ))} </TextField> ); } })} </Box> )