1

I have a HtmlInputElement that I define a onKeyDown handler on like so:

const keyDownHandler = (event: React.KeyboardEvent<HTMLInputElement>) => {
    console.log("The event target: ", event.target);
    console.log("The event target value: ", event.target.value);
    if(event.key === ...) {
        if(textValue.length === 0) {
              event.preventDefault();
              //Do other things.
        }
        ....
    }
};

I notice that if I type some input into the input box such as asd, I'll get the following outputs:

The event target:
    <input ... value="asd">

The target value: as

It seems my target value on the second print is always 1 input behind, and I don't see why its not returning my actual value.

I also define a onChange handler that triggers after my other on key down handler. After reading MDN I thought that the event.target.value would return the parametrized HTMLInputElement and its actual value, but it doesn't seem to.

Is there some other attribute I should be accessing in order to get the new computed value after the key press?

To add to this, I am trying to emulate backspace behavior in my jest test using testing-library.

I do this with userEvent.type(myInputBox, '{Backspace}');. In the browser I notice that my onChange handler is invoked, but not in jest test. I am trying to emulate this behavior because on the key down event I am not preventing default, and I want the default behavior to occur if the input box is not empty, otherwise do another action. In browsers, the default behavior occurs, but not in the test and I am not sure what is missing.

Niru
  • 1,407
  • 1
  • 28
  • 47
  • Does this answer your question? [console log the state after using useState doesn't return the current value](https://stackoverflow.com/questions/54867616/console-log-the-state-after-using-usestate-doesnt-return-the-current-value) – jharris711 Oct 04 '21 at 04:37
  • Not sure I understand. How would I use useEffect in my event handler since I am trying to get the new computed value after the key stroke? – Niru Oct 04 '21 at 05:48
  • You use it after. You set the dependency array to watch for the state change from the input: https://stackblitz.com/edit/react-zrxedu – jharris711 Oct 04 '21 at 13:07
  • I see, I think the other issue is that the change handler does not get executed in my jest class as well so depending on where I am testing I have different values. – Niru Oct 04 '21 at 16:30
  • I tried adding checks for selection start/end , getting new value, and adding a useEffect hook. In jest test none of them work, and only the onKeyDownHandler is invoked in the test. In chrome/Firefox/browsers though the value is correct. – Niru Oct 05 '21 at 06:15
  • Did you try onKeyUp() ? – Dostonbek Oripjonov Oct 05 '21 at 06:29
  • Just tried, with having both handlers and only preventing default on keyDown and condition met, but did not work. The keyUp handler does print the correct `event.target.value` in browser console, but not in jest/testing-library. – Niru Oct 05 '21 at 06:53

1 Answers1

2

I think you should try keyup or keypress methods.

  • KeyDown – when a key was pushed down
  • KeyUp – when a pushed button was released, and after the value of input/textarea is updated (the only one among these)
  • KeyPress – between those and doesn't actually mean a key was pushed and released.
Dostonbek Oripjonov
  • 1,508
  • 1
  • 12
  • 28
  • I tried with a keyUp and keyDown handlers, with `fireEvent.keyUp(domNode, {key: 'Backspace', code: 'Backspace', charCode: 8})`. Though the correct event handler executes, event.target.value does not print the correct value in the test, but does print in browser console. – Niru Oct 05 '21 at 06:51
  • 1
    I ended up mimicking the end value like this: `fireEvent.change(input, {target: {value: 'newValue'}})` and the test passed. I couldn't figure out what function was actually handling the delete/selection in browsers to emulate. – Niru Oct 05 '21 at 07:08