question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

React.FormEventHandler<HTMLElement> or React.ChangeEvent for Input?

See original GitHub issue

Environment

  • Package version(s): “@blueprintjs/core”: “^3.11.0”,
  • Browser and OS versions: Google Chrome: Version 71.0.3578.98 (Official Build) (64-bit) OS: Mojave 10.14.2

Question

Over at the Text Input Component, it is stated that the props for onChange should be:

React.FormEventHandler<HTMLElement>
Change event handler. Use event.target.value for new value.

Inherited from IControlledProps.onChange

However when I try to use React.FormEventHandler for my handleChange function, this shows up:

image

There’s a vague answer on stackoverflow which describes

ChangeEvent more suitable for typing form events

However, it does not explain why ChangeEvent is more suitable for typing form events.

Using React.ChangeEvent, the warning goes away. I am now able to edit my input fields on the UI. image

My questions are:

  1. Should I use ChangeEvent or FormEventHandler for my input?
  2. If it is FormEventHandler as suggested by the documentation on Blueprint, how do I deal with the warning TS2339: Property 'target' does not exist on type '(event: FormEvent<HTMLInputElement>) => void'.
  3. If input fields are supposed to use React.ChangeEvent, should we update IControlledProps.onChange?

My component code is straight forward

          <FormGroup helperText={props.helperText} intent="danger">
            <InputGroup
              value={props.email}
              onChange={props.onChange}
              name="email"
              /**
               * using type of "email" instead of "text"
               * Doing so constraints the value to a syntactically valid email address.
               * This generally has the format username@hostname.tld.
               * */
              type="email"
              placeholder="Enter e-mail address"
              large
              required
            />
          </FormGroup>

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:6 (2 by maintainers)

github_iconTop GitHub Comments

18reactions
jacekjagiellocommented, Feb 24, 2019

Hey, @havesomeleeway I think there is one misconception you have - FormEventHandler does not refers to the event itself, but it refers to event handler - the function that handles this event. Try this out:

handleChange: React.FormEventHandler<HTMLInputElement> = (event) => {
        this.setState({ [event.currentTarget.name]: event.currentTarget.value });
};

Note, that type React.FormEventHandler<HTMLInputElement> describes a handleChange function which is your event handler. In this case, Typescript will automatically recognize event parameter as React.FormEvent<HTMLInputElement> - which is the type you are looking for. Alternatively, you can describe only the event:

handleChange = (event: React.FormEvent<HTMLInputElement>) => {
        this.setState({ [event.currentTarget.name]: event.currentTarget.value });
};

But I’ll recommend you to go with first solution.

Also, note that you should use currentTarget instead of target - when typescript will recognize the type of event, it will actually warn you that name/value does not exist on type EventTarget which is the type of event.target

1reaction
jacekjagiellocommented, Feb 25, 2019

Actually, according to React.InputHTMLAttributes interface which InputGroup extends, you should use React.ChangeEventHanlder or React.ChangeEvent. I’ve missed that in first response. React.FormEventHadnler is meant to be used for form specific events like onSubmit.

Why would you recommend the first solution as opposed to the second one from a technical point of view?

I think as a general rule it’s better to add type to the whole function, rather than to individual arguments. This empowers reusability and pays off when you have a function that has multiple arguments. A good example of benefits can be found in @blueprintjs/select package. Consider this:

interface Item {
    label: string
    value: string
}

class App extends React.PureComponent<{}, {}> {
   render() {
       const items: Item[] = [
           { label: 'First item', value: 'first' },
           { label: 'Second item', value: 'second' },
           { label: 'Third item', value: 'third' }
       ]
       return <Select items={items} itemRenderer={this.renderItem} onItemSelect={console.log} />
   }

   // type for function
   // - no need to specify type for each of the arguments 
   // - you know execaly the type of renderItem function - more reable, better for docs
   // - reusable, you can add ItemRenderer to other functions, and they reamin consistent to single type
   private renderItem: ItemRenderer<Item> = (item, itemProps) => {
       return <MenuItem text={item.label} onClick={itemProps.handleClick} />
   }
   
   // type only for argument
   // need to specify type for each of the arguments
   private renderItem = (item: Item, itemProps: IItemRendererProps) => {
        return <MenuItem text={item.label} onClick={itemProps.handleClick} />
   }
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

Typescript input onchange event.target.value - Stack Overflow
Generally event handlers should use e.currentTarget.value , e.g.: const onChange = (e: React.FormEvent<HTMLInputElement>) => { const ...
Read more >
React Typescript cheatsheet: form elements and onChange ...
Quick cheat sheet with all the typings used for React forms. All the form elements events are the type React.ChangeEvent , where T...
Read more >
Forms and Events - React TypeScript Cheatsheets
List of event types​ ; ChangeEvent, Changing the value of <input> , <select> and <textarea> element. ; ClipboardEvent, Using copy, paste and cut...
Read more >
Type the onChange event of an element in React (TypeScript)
ChangeEvent <HTMLInputElement> . The ChangeEvent type has a target property which refers to the element. The element's value can be accessed on event.target....
Read more >
How to create React form with a single change event handler?
An HTML form allows users to enter data using input fields that accept text, password, email, number, color, telephone number, date, etc.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found