Home > Software design >  Why KeyboardEvent isn't working with this Input element in react?
Why KeyboardEvent isn't working with this Input element in react?

Time:10-16

I'm working with controlled input elements at work and I'm stuck.

Basically, I need to autofill some input elements in a form, but the problem is that I need to fill it in a way that simulates the user input (in this case, typing) in order to trigger the onChange function's logic. So, because of that. I need to emulate the typing behavior and not just set the value for the element.

Despite having searched for previous questions and reading docs about KeyboardEvent, I haven't been able to make this work.

Currently, I'm experimenting in a Codesandbox just for making things easier, but even with this simple environment, I can't manage to get this to work.

Here's the code and its Codesandbox link

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

Hopefully one of you guys could give me a hand with this.

Thanks for reading!

CodePudding user response:

Related to the comments:

I think that it shouldn't be necessary to be dispatching a keypress event to get your special effect logic to run.

For example, you can use a useEffect which just runs on initial render to trigger whatever special logic you want -- and this way you can just have a regular initial value for the form state.

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

CodePudding user response:

I couldn't fix the problem with Keyboard Event for my lack of knowledge about it, but I hope I managed to solve the problem of emulating a human autofill the input using the below code.


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;

  • Related