最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React: how to use event.data in onBeforeInput handler without TypeScript error - Stack Overflow

programmeradmin3浏览0评论

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 plaining that Property 'data' does not exist on type 'FormEvent<HTMLInputElement>'?

onBeforeInput={(e) => {
  handleInput(e.data);
  e.preventDefault();
}}

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 plaining that Property 'data' does not exist on type 'FormEvent<HTMLInputElement>'?

onBeforeInput={(e) => {
  handleInput(e.data);
  e.preventDefault();
}}
Share Improve this question asked Jun 24, 2021 at 0:53 AcornAcorn 50.6k30 gold badges141 silver badges179 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 3

I've found you can also do the following and you'll have no type errors:

onBeforeInput={(event: React.CompositionEvent<HTMLInputElement>) => {
  const data = event.data
}}

If you want to see what the next value in the input would be with the next value you can do the following:

onBeforeInput={(event: React.CompositionEvent<HTMLInputElement>) => {
  const str = event.currentTarget.value
  const sub = event.data
  const posStart = event.currentTarget.selectionStart || 0
  const posEnd = event.currentTarget.selectionEnd || posStart

  const nextValue = `${str.slice(0, posStart)}${sub}${str.slice(posEnd)}`
}}

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

The correct way to do this is:

onBeforeInput={(e: React.FormEvent<HTMLInputElement>) => {
  handleInput(e.nativeEvent.data);
  e.preventDefault();
}}

This is because react sends back a wrapper (SyntheticEvent) around the native event. This SyntheticEvent does not have a data property, so typescript is telling you the truth. Luckily react still provides a reference to the native event at nativeEvent. Keep in mind that typescript treats properties like data as any on the HTMLInputEvent so you'll need to be careful to handle all possible values that could exist there.

发布评论

评论列表(0)

  1. 暂无评论