En este artículo, abordaremos un problema común que se presenta al intentar sanitizar la entrada del usuario en un componente Autocomplete de MUI dentro de una aplicación React. A menudo, los desarrolladores quieren restringir la entrada a ciertos caracteres válidos, pero pueden encontrarse con que la sanitización no se aplica correctamente, especialmente en el caso de la escritura en el campo de texto.
Lo que se tiene
El objetivo es sanitizar la entrada ingresada en el componente Autocomplete para evitar que el usuario ingrese caracteres que no tienen sentido, permitiendo solo números y dos puntos.
Intentos realizados
Se ha creado un componente que incluye tanto un input nativo como un componente de Autocomplete. Se estableció un valor controlado para ambos componentes, y se implementó una función de sanitización que reemplaza cualquier carácter que no sea un número o dos puntos.
const Form = () => {
const sanitize = value => value.replace(/[^0-9:]/g, '')
const [value, setValue] = useState('')
return (
<>
<input type="text" value={value} onChange={(e) => { setValue(sanitize(e.target.value)) }} />
<Autocomplete
options={['12:00', '13:00', '14:00', '15:00', '16:00', '17:00', '18:00']}
value={value}
inputValue={value}
onChange={(_, value) => { setValue(sanitize(value || '')) }}
freeSolo
renderInput={(params) => (
<TextField {...params} label="Value" value={value} onChange={(e) => {
setValue(sanitize(e.target.value))
}} />
)}
/>
</>
)
}
Problema identificado
A pesar de que el input nativo funciona correctamente, el componente MUI no sanitiza adecuadamente la entrada del usuario. Al escribir letras en el campo, estas no se filtran de inmediato, y solo desaparecen al ingresar un número después de ellas. Esto se debe a la forma en que MUI gestiona el valor de entrada y la lógica de actualización.
Solución propuesta
Para solucionar este problema, se sugiere realizar los siguientes ajustes:
- Modificar el valor de
inputValue
en el componente Autocomplete para que use el estado ya sanitizado. - Asegurarse de que la función
sanitize
se aplique correctamente en todos los eventos de cambio, tanto en el input como en el Autocomplete.
const Form = () => {
const sanitize = value => value.replace(/[^0-9:]/g, '')
const [value, setValue] = useState('')
return (
<>
<input type="text" value={value} onChange={(e) => { setValue(sanitize(e.target.value)) }} />
<Autocomplete
options={['12:00', '13:00', '14:00', '15:00', '16:00', '17:00', '18:00']}
inputValue={sanitize(value)} // aplicar la sanitización aquí
onInputChange={(e, newValue) => { setValue(sanitize(newValue)) }} // usar onInputChange para actualizar el valor
freeSolo
renderInput={(params) => (
<TextField {...params} label="Value" onChange={(e) => {
setValue(sanitize(e.target.value))
}} />
)}
/>
</>
)
}
Con estos cambios, el componente debería comportarse como se espera, permitiendo solo caracteres válidos y actualizando la vista en tiempo real durante la escritura.