Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React: how to use event.data in onBeforeInput handler without TypeScript error

So the event received by an onBeforeInput handler is typed as React.FormEvent<HTMLInputElement>. This is quite a general type, and doesn't include the data property.

As far as I'm aware the events that onBeforeInput receives (nativeEvents being KeyboardEvent in Firefox, TextEvent in Chrome) will have the data property.

What's the right way to write a handler that uses event.data without TypeScript complaining that Property 'data' does not exist on type 'FormEvent<HTMLInputElement>'?

onBeforeInput={(e) => {
  handleInput(e.data);
  e.preventDefault();
}}
like image 796
Acorn Avatar asked Jun 24 '21 00:06

Acorn


People also ask

How do you pass parameters to an event handler React?

Passing the event object of react as the second argument. If you want to pass a parameter to the click event handler you need to make use of the arrow function or bind the function. If you pass the argument directly the onClick function would be called automatically even before pressing the button.

How do you trigger events in React?

You could use the ref prop to acquire a reference to the underlying HTMLInputElement object through a callback, store the reference as a class property, then use that reference to later trigger a click from your event handlers using the HTMLElement. click method.

How do you use events in ReactJS?

Handling events with React elements is very similar to handling events on DOM elements. There are some syntax differences: React events are named using camelCase, rather than lowercase. With JSX you pass a function as the event handler, rather than a string.

Which event can be used to stop event propagation in React?

stopPropagation() The stopPropagation() method of the Event interface prevents further propagation of the current event in the capturing and bubbling phases.


1 Answers

I just check the type definition and found this,

type of e is FormEvent<HTMLInputElement>,

Then the FormEvent is defined as,

interface FormEvent<T = Element> extends SyntheticEvent<T> {
}

The FormEvent is extended the SyntheticEvent, which defined as,

interface SyntheticEvent<T = Element, E = Event> extends BaseSyntheticEvent<E, EventTarget & T, EventTarget> {} 

And when I check the definition of BaseSyntheticEvent, I found this,

interface BaseSyntheticEvent<E = object, C = any, T = any> {
    nativeEvent: E;
    currentTarget: C;
    target: T;
    bubbles: boolean;
    cancelable: boolean;
    defaultPrevented: boolean;
    eventPhase: number;
    isTrusted: boolean;
    preventDefault(): void;
    isDefaultPrevented(): boolean;
    stopPropagation(): void;
    isPropagationStopped(): boolean;
    persist(): void;
    timeStamp: number;
    type: string;
}  

Here we don't have a property call data. Then I just saw that there is a type call, CompositionEvent which extends SyntheticEvent.

interface CompositionEvent<T = Element> extends SyntheticEvent<T, NativeCompositionEvent> {
    data: string;
}

And it has the field data;

So I did,

<input type="text" onBeforeInput={(e:SyntheticEvent) => { 
        let event = e as CompositionEvent; 
        console.log(event.data); 
}} /> 

Or,

interface CustomEvent extends SyntheticEvent {
  data ?: string
}
<input type="text" onBeforeInput={(event:CustomEvent) => { 
        console.log(event.data); 
}} /> 
like image 186
Dilshan Avatar answered Sep 29 '22 00:09

Dilshan