Estoy trabajando con elementos de entrada controlados en el trabajo y estoy atascado.
Básicamente, necesito completar automáticamente algunos elementos de entrada en un formulario, pero el problema es que necesito completarlo de una manera que simule la entrada del usuario (en este caso, escribir) para activar la lógica de la función onChange. Entonces, por eso. Necesito emular el comportamiento de escritura y no solo establecer el value para el elemento.
A pesar de haber buscado preguntas anteriores y haber leído documentos sobre KeyboardEvent , no he podido hacer que esto funcione.
Actualmente, estoy experimentando en Codesandbox solo para facilitar las cosas, pero incluso con este entorno simple, no puedo lograr que esto funcione.
Aquí está el código y su enlace Codesandbox
import { useRef, useState, useEffect } from "react"; import "./styles.css"; export default function App() { const [state, setState] = useState(); const inputRef = useRef(); const event = new KeyboardEvent("keypress", { key: 99 }); useEffect(() => { inputRef.current.dispatchEvent(event); }, [inputRef]); const onChange = (e) => { setState(e.target.value); }; return ( <div className="App"> <h1>{state}</h1> <input type="text" id="name" onChange={onChange} ref={inputRef} value={state} /> </div> ); }Ojalá alguno de ustedes me pueda dar una mano con esto.
¡Gracias por leer!
No pude solucionar el problema con Keyboard Event por mi falta de conocimiento al respecto, pero espero haber logrado resolver el problema de emular un autocompletado humano con el siguiente código.
function AutoFillInput({ finalValue }: { finalValue: string }) { const [inputValue, setInputValue] = useState(''); const [sliceStart, setSliceStart] = useState(0); const changeHandler = useCallback((event) => { setInputValue(event.target.value); }, []); useEffect(function handleFinalValueChange() { setInputValue(''); if (sliceStart < finalValue.length) setSliceStart(x => x + 1); }, [finalValue]); useEffect(function handleSlice() { setInputValue(finalValue.slice(0, sliceStart)); if (sliceStart < finalValue.length) { setTimeout(() => { setSliceStart(x => x + 1); }, 800); } }, [sliceStart]); return ( <input value={inputValue} onChange={changeHandler} placeholder={'Auto fill input'} /> ) } function App() { return ( <div > <AutoFillInput finalValue={'hello world'} /> </div> ); } export default App;Relacionado con los comentarios:
Creo que no debería ser necesario enviar un evento de keypress de tecla para que se ejecute la lógica de efectos especiales.
Por ejemplo, puede usar un useEffect que solo se ejecuta en el procesamiento inicial para activar cualquier lógica especial que desee, y de esta manera puede tener un valor inicial regular para el estado del formulario.
import { useState, useEffect } from "react"; import "./styles.css"; export default function App() { // In the useState call, you can initialize the value. const [state, setState] = useState("initial value"); const specialEffectFunction = () => { // here's the code for the special effect you want to run on load console.log('this is the special onChange effect') } useEffect(() => { // This will trigger the special function which you want to run // when the app loads specialEffectFunction(); // if it really HAS to be the `onChange` function that's called, // then you'll need to call that with a fake ChangeEvent.. but I don't // think that should be necessary... }, []) const onChange = (e) => { setState(e.target.value); }; return ( <div className="App"> <h1>{state}</h1> <input type="text" id="name" onChange={onChange} value={state} /> </div> ); }